Private vs public

Started by
10 comments, last by Zoner 13 years, 2 months ago
Usually I employ private variables, but when it comes to games I feel like maybe there is no need for those, and I should go with public. Am I wrong, or is there no need for private variables if the program is a game? (or at least not a strong need)
Advertisement
Could you explain why you think there is (less) need?

I imagine you mean that, because often game code is a one timer, and thrown away after usage. But how can you know? What, if in ten years you have a deep desire to do a successor to your game?
No there's always a place for public and private. use private variables when you don't want to expose unnecessary internal aspects of a class. Public variables for exposing functionality
J.W.

Usually I employ private variables, but when it comes to games I feel like maybe there is no need for those, and I should go with public. Am I wrong, or is there no need for private variables if the program is a game? (or at least not a strong need)
[font="Courier New"]private[/font] is used as a software engineering tool to achieve a stable code-base where you're easily able to reason about class invariants.

If your game is only made up of 100 lines of code, then maybe you don't need encapsulation to ensure your code is correct... but if you game is made up of 1M lines of code, then good engineering practice becomes a lot more important.

Whether you're making a game or not doesn't really affect whether it's important, but the size of the project and the number of members on the programming team does -- larger projects require more formal engineering practices, whereas on smaller projects you're able to fly by the seat of your pants.

Could you explain why you think there is (less) need?

I imagine you mean that, because often game code is a one timer, and thrown away after usage. But how can you know? What, if in ten years you have a deep desire to do a successor to your game?


It's not just a one timer, but I'm making a game rather than an engine that will be used by others. I could, like you said, want to use it later on, but I doubt that having things public rather than private would give me that much trouble. But I'm asking because I could be wrong, as I barely have any experience in this field.


[quote name='pcgamer' timestamp='1296539026' post='4767822']
Usually I employ private variables, but when it comes to games I feel like maybe there is no need for those, and I should go with public. Am I wrong, or is there no need for private variables if the program is a game? (or at least not a strong need)
[font="Courier New"]private[/font] is used as a software engineering tool to achieve a stable code-base where you're easily able to reason about class invariants.

If your game is only made up of 100 lines of code, then maybe you don't need encapsulation to ensure your code is correct... but if you game is made up of 1M lines of code, then good engineering practice becomes a lot more important.

Whether you're making a game or not doesn't really affect whether it's important, but the size of the project and the number of members on the programming team does -- larger projects require more formal engineering practices, whereas on smaller projects you're able to fly by the seat of your pants.
[/quote]

I realise the need for private variables in case we're working as a team. But even if it is a large project, but which I'm doing on my own, would it still be as important as the first?


No there's always a place for public and private. use private variables when you don't want to expose unnecessary internal aspects of a class. Public variables for exposing functionality

What functionality? Would coordinates, health and armor for example be part of that functionality? Or would they be considered an internal aspect of the class?


(BTW, thank you all for your replies!)

I realise the need for private variables in case we're working as a team. But even if it is a large project, but which I'm doing on my own, would it still be as important as the first?
Yes. Code that you wrote months (or weeks) ago may as well have been written my someone else.

Encapsulating certain bits of data/functionality away from the desired interface is an important way of writing bug-free code. but... IMO it's a lesson best learned through practice. I was once highly confident in my programming skills, felt able to tackle any problem, but still shunned private. "Why limit yourself" I would ask myself, when considering this seemingly useless keyword.
Several buggy projects later, with similar functionality duplicated around the code, the same data being set by disparate modules and bug-fixes spread across multiple files, I realised that I had a flawed understanding of object-oriented design.
If a class doesn't have any invariants, then it's fairly safe to make it's members public, but it turns out that such classes often aren't very good abstractions, and may not have needed to be objects in the first place.
So, if you're comfortable avoiding private, then keep doing what you're comfortable with, until you feel the need to try out some alternate approaches ;)
What functionality? Would coordinates, health and armor for example be part of that functionality? Or would they be considered an internal aspect of the class?[/quote]Many physics systems prefer you modify coordinates by applying forces to an object, rather than directly modifying the actual position. In that case, the adjustment of the position is private functionality.

Does health have any invariants? One could be that health must be between 0 and 100 (inclusive). If you've got a rule like that, then one approach would be to make the variable private and make a public 'setter'bool Character::SetHealth( int newHealth )
{
if( newHealth >= 0 && newHealth <= 100 )
m_Health = newHealth;//only set the value if it's valid
return m_Health == newHealth;//return true/false indicating if the newHealth value was actually set.
}
But usually getters/setters aren't very useful. Usually a better design incorporates some logic about how the members should change, instead of just guarding against bad changes, e.g.int Character::TakeDamage( int damage, bool ignoreArmour )
{
assert( damage >= 0 );
if( !ignoreArmour )
{
m_Armour -= damage;
if( m_Armour < 0 )
{//there is some damage left over after depleting all the armour
damage = -m_Armour;
m_Armour = 0;
}
else
damage = 0;//armour absorbed all the damage
}
m_Health -= damage;
if( m_Health < 0 )
m_Health = 0;
return damage;//return the actual amount of health that was removed (after armour calculations)
}
Now, with the above, instead of just making sure that people don't set invalid health values, we've made it so people don't have to set health values at all. Instead we've invented a new concept -- damage -- and created an interface for dealing damage. Not only does this ensure that health values are always valid, it centralises the logic for dealing with armour at the same time -- no other part of the code base should have to know exactly how health/armour calculations work any more, and instead of our objects just being blobs of data, they're interesting interfaces that you can interact with instead. In any class, everything public is the interface, and everything private is stuff that the user of the class doesn't have to know about. In general, the less that each part of the code-base knows about, the better.

Part of the reason for doing this is, if you find there's a bug in the way armour is being reduced, you know that it must be in the above function somewhere (or actually, somewhere in the class that owns the above function). If armour was a public variable, then the bug could literally be in any file of your code base.

[edit]mrwonko's example below is a good one too -- often you want to call a function when a variable changes. If anyone can change things, then you'll have a hard time actually enforcing that rule (i.e. it's easy to forget to call the function if you change the variable).
[quote name='jdub' timestamp='1296542173' post='4767841']
No there's always a place for public and private. use private variables when you don't want to expose unnecessary internal aspects of a class. Public variables for exposing functionality

What functionality? Would coordinates, health and armor for example be part of that functionality? Or would they be considered an internal aspect of the class?[/quote]
Making variables private gives you more control. For example you may want an enemy to die when his health goes below 1, you've got a Die() function for that. By making health private and using a SetHealth(amount) or LowerHealth(amount) function, you can check for the low health condition in that function and call Die() if necessary.
You also have finer control over the validity of the values - for example you can keep the health from being set to something above the maximum.

--edit--
Ninja'd
The general rule is not to use 'private' to protect data, rather it should serve as a means to enforce a particular programming convention or habit when it comes to interfacing with objects. That said, I don't use private scope for things that are meant to be treated as a POD type. Vectors, matrices, vertex data, material properties, light properties, and simple messaging structs fall into that category. Writing getter and setter methods for those seem so redundant, when all you do is assign values to their members. On the other hand, more complex objects get the black box treatment that can be only manipulated through a few methods.
Latest project: Sideways Racing on the iPad
To explain that in an easy sentence, you should avoid setting variables on objects, and instead TELL YOUR OBJECTS WHAT TO DO.

Look at the above example, where Hodgman has a class with a TakeDamage function. You could have a function like this as a part of a base class for creatures. Then you can subclass that creature class for all different kinds of creatures (players, npcs, bosses, or even damageable props). Then you can have a list of objects and you can loop through them and just call the TakeDamage function on all of them. They will all run their own TakeDamage functions.

So you have a room full of game objects, and you throw a giant fireball in there. All you have to do is call the TakeDamage function on all the objects, and now they all act accordingly. The enemies all burn up for massive damage and kick the bucket. The destructible props all burst into flames. The random passerby NPCs all take major damage and die. The plot NPCs either don't take damage, or take damage but never go blow 1 HP. The other players in the area may or may not take damage depending on any number of variables (no friendly fire, no friendly fire on team mates, anything goes)....

Each type of object will call the base TakeDamage(), and may or may not implement their own version of the function with added functionality. So instead of littering your code with all kinds of random variable assignment statements, each possibly containing a bug or maybe bad logic that you will never track down, this seemingly complex interaction can be handled with something as simple as:

foreach gameobject o in fireball_radius
o.TakeDamage(DAMAGE_TYPE_ELEMENTAL_FIRE,500)
One thing worth mentioning is the whole data orientated programming movement thats very popular amongst commercial developers.

Mike Acton from Insomniac Games is one of the main components.

Basically it relies on very clear data sets of your data, then using more the encapsulations of Managers which manage that data. So for example character AI data would be all sequential blocked together where you'd use it, and rather than encapsulating a Update method on a AICharacter object, you'd instead have AIManager which would access like data at once.

In this paradigm the data would be exposed potentially through the old C struct style declarations where everything is public because your not so much interested in the traditional object abstraction, your more interested in the data.

Classes/Objects and data orientated design aren't mutually exclusively, they can co-exist but you have a different way of structuring your data/classes etc.

Read some more if you like:
http://gamesfromwithin.com/data-oriented-design-now-and-in-the-future
http://altdevblogaday.com/pages/how-does-it-work
http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BData%20Oriented%20Luddites%5D%5D
http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BMoore's%20Law%20vs%20Duck%20Typing%5D%5D

The traditional OO view does have many advantages, mainly in regards to potentially higher gains in maintainability. DoD has definite speed advantages and forcing a clean/simple hierarchy can have some advantages in terms of readability at times, but sometimes OO abstractions are much easier on the human brain.

If your starting out in your early projects I'd recommend starting out with OO but keep an open mind its not the only approach.

This topic is closed to new replies.

Advertisement