Yet again, law of demeter
Each unit should only talk to its friends; don’t talk to strangers.
Did it make any sense? If not, continue reading.
Imagine you have the following classes. User holds a reference to Account and Account holds a reference to Credentials and Image.
And you have a requirement to show the avatar and you hold a reference to user object.
Since you have access to user object, then you can easily get the required information.
But do you see anything wrong with this implementation? What problems would you have?
- First of all, by getting avatar that way, we’ve increased the coupling, now Foobar has coupling with User, Account and Image which means any change on these classes will affect Foobar.
- Imagine that your implementation has been changed and avatar image should be taken by somewhere else, let’s say we have profile class and now profile class keeps the required image. In that moment, you need to go through all places and change this implementation.
- What if getAccount() returns null? You need to make a null check. Assume that it goes more than one level, then it will become more complex.
- If you don’t know the details, you would never know where exactly avatar image is. Who would guess that avatar image is inside account?
- And lastly and most importantly regarding to accessibility, user has full access to the account and expose this permission to everyone who has access to User. Account holds credentials and if you have access to user, you can easily get credentials as well.
To emphasize the last point with a real example, imagine that you go to the bank and you have access to enter to the bank, but it doesn’t mean you have access to everything. You can’t just go to any machine and get money without the permission, you basically ask your bank to do this. The same rule applies here. By having access to the user object shouldn’t mean to access everything. Client should not know about account details at all. (unless there is no good cause to expose it)
We’ve introduced a new wrapper method which is called getAvatar() inside User class.
- We’ve increased the readability, any developer would notice easily to how to get avatar. (high cohesion)
- You don’t need to deal with NPE (one billion dollar answer)
- You don’t need to know implementation detail of this method, if the implementation changes, it won’t affect you. (partially abstraction)
- You don’t expose the account details anymore, user exposes only the required information (information hiding)
- Foobar doesn’t need to know anything about account anymore (low coupling)
- We have now another method to maintain, imagine that you have many cases like that.
Now let’s read the definition again
Each unit should only talk to its friends; don’t talk to strangers
We did exactly what we are told.