Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unencapsulated means Unchangeable?

I came across this line in Effective C++:

Public means unencapsulated, and practically speaking, unencapsulated means unchangeable, especially for classes that are widely used.Yet widely used classes are most in need of encapsulation, because they are the ones that can most benefit from the ability to replace one implementation with a better one

What does the author mean by "Public means unencapsulated, and practically speaking, unencapsulated means unchangeable"?

And how is unencapsulated unchangeable?

like image 554
Suhail Gupta Avatar asked Dec 17 '22 12:12

Suhail Gupta


2 Answers

The general idea is simple. If you make something public, then someone can and probably will use it. Therefore, if you change something that is public, all of the code that uses it immediately breaks. Breaking people's code is bad; it tends to lead to them not wanting to use your code anymore, since now you've forced them to rewrite all of their stuff just because you wanted to use a different type or something.

The public interface is a contract between the implementation of the class and the user of it. Changing that contract, particularly without advanced notice, is considered very rude.

If all of your code is internal, that's fine. But if it's not, if you're making a library for others to use (whether locally or just selling a library), then people are less likely to be happy about interface changes.

It isn't a matter of rules of C++; it's simply a matter of rules of interface design. Since public things are part of the interface, you must be careful about what you make public.

like image 127
Nicol Bolas Avatar answered Dec 19 '22 02:12

Nicol Bolas


Encapsulation is the idea that you can access the data member of a class only through interface methods. The effect of using a method is "hiding" the actual implementation of the data member, so that you can change it without the need to change the code that uses that class through the interface methods (provided you don't change the way they are defined).

On the other hand, if you don't use interface methods to hide the data member implementation, all your code that uses it will need to be modified in front of any change in the data member.

Say that you have a class with a vector of strings containing a list of names. If you make public that vector, then all other classes can decide to directly use it, and access the strings it contains by their index in the vector (the index acts as a key to identify the string, say).

Later, you could decide you need a map to manage all those strings (your requirement have changed). You change the data member definition to a map and your code will not compile anymore. This is the meaning of "practically unchangeable".

The "right" way to manage this through encapsulation is making the data member private and define an interface method like:

std::string getStringWithKey(int index);

this method will access the vector in the first implementation, and the map in the second case. All this in a transparent way: the code that uses the method (instead of accessing directly the data member) will not need to be modified, so you can change the data member implementation as you like at almost no cost.

This is an oversimplification, because design of interfaces is not a simple matter and interfaces also do change, but I hope it helps clarifying things.

like image 36
sergio Avatar answered Dec 19 '22 03:12

sergio