public and private, when would you use which

BlitzMax Forums/BlitzMax Beginners Area/public and private, when would you use which

Bremer(Posted 2005) [#1]
I am looking at perhaps making a module out of a set of types and functions, but what should be labeled public and what should be labeled private, and what is the impact of using these?


Bot Builder(Posted 2005) [#2]
private functions are functions that are used only internally to the module and shouldn't be messed around with because you could easily do something wrong.

public is the default for functions and means that they can be accessed - it cancels a previous private decleration for the functions following it.

These might also apply to types and globals but i'm not sure.


kyoryu(Posted 2005) [#3]
The two words used to generally describe this problem are 'interface' and 'implementation'.

All interface functionality should be public. These are the methods and functions which things that are not the module use to manipulate the module/type/etc.

The implementation itself, ie what it does underneath the surface, should be private.

The general reason for this is that by separating the interface and implementation, you allow yourself the luxury of changing the implementation without having to rewrite code that uses the module. I'm going to use an example which I don't think is possible in BMax, just because it simplifies the question.

Assume you have a type called 'TPosition'. It has two fields, x and y. Ideally, these fields would be private, and would be accessed by methods to read and set them.

The reason you do this is very simple. If you, in the future, realize that instead of just being members, that X and Y should be calculated somehow, it becomes easy to change. If you subclass your position type with something that's always at 0,0, it's easy to just override the methods to always return 0.

So Methods like 'getX(), getY(), setX( x:Int ), setY( y:Int )' are your interface. They're how outsiders deal with the module. They do not reflect what the module itself does internally.

If, instead, you just write directly to your X and Y fields, and then you need to change how they're stored or calculated, you have to change every single instance of your code that accesses them.


Bot Builder(Posted 2005) [#4]
Yeah, that's why bmax needs properties - so we can write code for getting and setting variables without all the get/set prefixes.


Bremer(Posted 2005) [#5]
I seem to remeber reading somewhere that types cannot be private in Bmax, would there be some truth to that? If so, that would prevent people from doing what you describe Kyoryu.


kyoryu(Posted 2005) [#6]
zawran:

Yeah, that's why I pointed out that my example probably wouldn't actually work in BMax :)

Still holds true for modules though... keep your interface public, your implementation private.

Oh, and it doesn't stop you from hiding your type fields behind an interface, it just makes it harder to enforce.


FlameDuck(Posted 2005) [#7]
Yeah, that's why bmax needs properties
"Properties" are just methods that wrap fields. Considering BlitzMAX does not allow for multithreading, why would you ever want to use a method, rather than just accessing the field directly?


kyoryu(Posted 2005) [#8]
FlameDuck:

a) set methods are useful to perform error checking, other validation, or secondary functions when a variable is set. In my 'position' example, it may be useful to check for collision or bound when setting the x or y coordinate.

b) there may be a time in the future where you realize that a single property field was not the best way of handling the data. Maybe you realize that the data needs to come from a different place, like a contained member, to weed out redundancy, or that it needs to be calculated on the fly. In this case, using a get method instead of simply accessing the variable directly allows you to change how the value is handled behind the scenes without changing any of your source that uses the type/module in question.

Separation of interface and implementation is GOOD.


Bremer(Posted 2005) [#9]
When coding something that is to be a module, would it be advisable to do something like the following:

Private
Type zsLayer
Field texture:zsResource
Field zorder
Field visible

Method setVisible( VISIBLE )
self.visible = VISIBLE
End Method
End Type
Public

Function zsLayerVisible( visible )
zsLayer.setVisible( visible )
End Function


If I understand it correctly, that would let the user see the zsLayerVisble function but not the type and its methods. It would probably make it easier for the casual programer to use rather than having to figure out all the fields and understanding how they relate.

I wouldn't mind hearing others viewpoint on this.