Understanding the encapsulation is easy: your objects and methods must hide the implementation. You have to look at the methods name and understand “what it does” but never “how it does”. Rules, variables or instances which are necessary to do what is being done must to be hidden in a method; It helps to reuse code and understand more fast and easily only what is necessary.
When a class knows a lot about implementation of another class or when this class knows about some business rules that don’t belong to this class scope.
Tell, Don’t Ask
There is no better explanation than that:
Tell-Don’t-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do. This encourages to move behavior into an object to go with the data. Martin Fowler
If your code needs to ask something to an object to decide what has to be done, an inappropriate intimacy is happening!
Law of Demeter
A class can’t know more than the class who is being invoked. If a class A call a method from instance of class B, A must not know who B is invoking or what B is calling inside the method. Codes like that’s below must be avoided.
Who is calling B knows it has a C instance, and knows C has an instance of D, which has a method called aMethod(). Who is calling B know a lot about B, C and D. It’s an inappropriate intimacy! A great way is:
Now I don’t know that inside aMethod() the B instance is calling a C instance; So, I don’t what is happening inside aMethod(). I know what this method does, but I don’t know how it is being done. It’s the description of encapsulation, isn’t?!
Another point is that we are avoiding the propagation of change. For example, if we change something on aMethod(), only C will need to be adapted, won’t be necessary to change B and A. Only who depends directly from a class changed will need to be changed too.
Getters and Setters
Be careful of getters and setters, specially setters. Law of Demeter shows us a problem with getters but setters are specially problematic for the encapsulation. Setters allow external classes add values on our class and if that it is not very controlled, taking care of rules, it can break the encapsulation. Some developers preach we must not create this kind of methods for all of our attributes but we should use getters and setters only when it’s necessary.