Advertisement

Encapsulation

Started by February 19, 2002 01:57 AM
8 comments, last by Tac-Tics 22 years, 9 months ago
Why is encapsulation important in OOP? Is it unsafe to have a few public members in a class? For games, does it make it easier to hack if you don''t encapsulate things? I''m asking this because if there''s some important reason to encapsulate every data member in a class, then I''m gonna have to rewrite a lot of my code for the game I''m making =-) I keep most of the basic data private, but for things like my homemade Vector class and such, I leave it public so I don''t have to write accessors and modifiers for it. Can anyone lend me a hand? "I''''m not evil... I just use the power of good in evil ways."
Encapsulation isn't so much to keep others from messing up your code, although it can help. Its main focus is to keep YOU from messing up your code.

Here's an analogy:
Assume you are an OO class. Your name is a data member. If you are encapsulated properly, you can't accidentally change your name...and neither can anyone else. If you aren't encapsulated correctly, the first time you, or someone you know, introduce yourself as Barbara Ballsalot you have changed your name (and possibly your gender). Proper OOP technique would require that you have to use a function to get it done.(The first case would take court proceedings, and in the second case, medical intervention)

As for rewriting your game, if it were me, I'd hide the data members. By forcing your code to use functions to reach the members you can write the function to check for valid parameters at the same time.

ShadeStorm, the Day_Glo Fish

[Edit: Man, I need a new keyboard.]

Edited by - ShadeStorm on February 19, 2002 3:34:37 AM
ShadeStorm, the Day_Glo Fish
Advertisement
It''s a misconception that encapsulation is only a good OO practice, it''s good programming practice period. The benefits of good encapsulation become more apparent the larger your project gets, and the more people that work on it. Good encapsulation helps control various symptoms of poor design, such as: rigidity, fragility and immobility. It helps achieve change throughout the lifetime of an application, it helps limit change to isolated parts of an application, and it helps in reusing components of an application.

There''s far more to good encapsulation than simply making all class data private, and providing accessor functions. That is actually called data hiding, and it is not really the same thing as encapsulation. In fact, if you are writing a lot of simple accessors and mutators with a 1-to-1 correspondence with the data members, then you are not encapsulating your class.

The aim of encapsulation from this point of view is to protect clients of the class from having to deal with the implementation details. In other words, they shouldn''t really need to understand what data members a class has for them to manipulate. Rather, they should request the class to perform some action at a higher semantic level than "set x to 5", and the class will decide how the member data should be changed to reflect the new state.

--
1st law of programming: Any given program, when running, is obsolete.
There are a simple example that clarify the advantages of encapsulation (data hiding aspect).

Think that you are made a math library related to 2D (complex number math is the same example but many people think that complex numbers are really complex ;-)

If you code (cartesian basis):

class Vector3D
{
public:
float x, y, z;
};

then you have to code:

float dotProduct(Vector3D & a, Vector3D & b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}

Vector3D vecProduct(Vector3D & a, Vector3D & b)
{
Vector3D result;
result.x = a.y * b.z - a.z * b.y;
result.y = a.z * b.x - a.x * b.z;
result.z = a.x * b.y - a.y * b.x;
return result;
}

What happen if you need to change later to a spherical basis:

class Vector3D
{
public:
float ro, theta, phi;

float x();
float y();
float z();
};

ALL your other code would go to thrash. You need to fix it everywhere.
However, if you were encapsulate access to internal representation of data, then you could change the internal implementation every time that you need it, without need to change no line in the client code.
Pepe: I disagree. For simple things like vector class, direct access to members can be/is better than using accessor/modifier functions, because:

1. These classes usually represent the only way you would write those particular classes. If I asked any number of people to write a vector class for me, I probably would get the same definition (float x, y, z).

2. These classes should be compact and fast. You will need a lot more keystrokes to do vector math if you need to call get() and set() functions each time you need a coordinate. When you changed the vector definition, you really defined a wholly different things rather than changed implementation. I would say the first class should have been named Vector3DCartesian and the second one Vector3DPolar. If you try using accessors in your dot/cross product routines that calculate components instead of just returning them, your performance will very quickly go to zero. This I think is a design question: the vector class is really meant to be a cartesian vector, not just any vector. I doubt that you will make such drastic changes to your vector classes in any of your programs.

Conclusion: encapsulation is good, but sometimes structs (in the sense that data is the focus) are better than classes.
---visit #directxdev on afternet <- not just for directx, despite the name
quote: Original post by IndirectX
Pepe: I disagree. For simple things like vector class, direct access to members can be/is better than using accessor/modifier functions, because:

1. These classes usually represent the only way you would write those particular classes. If I asked any number of people to write a vector class for me, I probably would get the same definition (float x, y, z).

2. These classes should be compact and fast. You will need a lot more keystrokes to do vector math if you need to call get() and set() functions each time you need a coordinate. When you changed the vector definition, you really defined a wholly different things rather than changed implementation. I would say the first class should have been named Vector3DCartesian and the second one Vector3DPolar. If you try using accessors in your dot/cross product routines that calculate components instead of just returning them, your performance will very quickly go to zero. This I think is a design question: the vector class is really meant to be a cartesian vector, not just any vector. I doubt that you will make such drastic changes to your vector classes in any of your programs.

Conclusion: encapsulation is good, but sometimes structs (in the sense that data is the focus) are better than classes.


Think inline. Inline function calls to something like a vector class for set and get methods will improve preformance. Protect the integrity of the data. Another benefit of using classes for vectors is the namespace which is inherited which can pretty much garuentee that your "Vector" doesn''t interfear with another "Vector" implementation say from STL, or any number of math libraries.

Advertisement
I think you misunderstood my point. I said that it takes more keystrokes to use accessor/modifier functions with, say, vector, and since you use them a lot, it''s tedious. As for performance, I meant that if you changed the vector definition from cartesian coordinates to polar, then you probably have to change all code that manipulates that vector, otherwise it will be painfully slow.
---visit #directxdev on afternet <- not just for directx, despite the name
encapsulation has little to do with people hacking your code.

encapsulating your objects makes people only interact with your object in the intended way.
some benifits:
-you have control over the minions using your class.
-you may have more readibility.
-you can enfore data integrity.
-you can say your an object oriented guru (not that you necessarily would be).
--

as far as get/ set goes, i dont think any ''naked'' data should be public.
if your developing some game that no one will ever see or care about, then fine, be lazy, and poorly encapsulate, but otherwise,

there is no way to tell how future users might try to interact with your class. by providing naked data, your users can be exposed to implementation issues that have nothing to do with how the user should be using your class.

its probably something like data integrity. its necessary to enforce integrity because users may not know the long term effects of using you class in a poor or wrong way.
encapsulation also enforces the ''black box'' phenomena, its not necessary to know about all the gears and springs in the box, so as long as the box does what its ''sposed to do.

as far as typing goes, its called crtl-x/c/v/z/y...
quote: Original post by EvilCrap
as far as typing goes, its called crtl-x/c/v/z/y...

What does "Ctrl-Y" do?
quote: Original post by IndirectX
I think you misunderstood my point. I said that it takes more keystrokes to use accessor/modifier functions with, say, vector, and since you use them a lot, it''s tedious. As for performance, I meant that if you changed the vector definition from cartesian coordinates to polar, then you probably have to change all code that manipulates that vector, otherwise it will be painfully slow.


I shouldn''t grace this statement with a response. I''m _really_ hoping this is a troll.

Anyone whose done real object-oriented coding knows that in medium to large sized programs object-oriented code actually results in less lines of code being generated because code reusability is high.

Anyway, even if it is a lot to type, use a REAL editor like ViM! Short cuts are a programmer''s best friends. I rarely type the same thing twice. In fact I rarely leave command mode.

As far as the statement concerning different coordinate types, well a good design would be able to do operations upon a vector utilizing any coordinate system. The change would be minimal if the design were done properly. Good design doesn''t include just one class. It has more to do with how well the classes interface with each other.

Peace all, no offense intended,
RandomTask

This topic is closed to new replies.

Advertisement