Sunday, 28 December 2014

Creating good interfaces - The Law of Demeter




For the ones who are used to the OOP approach, the term Interface,
may relates to a structure that will determine the behaviour that other structures will assume. However, when talking about Software Engineering concepts they are more than that. They help to define Software abstractions that can be widely used in a software system. Interfaces can also be seen as what structures exposes (i.e make public), to the world. Once you make something public, you're creating a chance to other structures rely on and from this point, you'll need to maintain this relationship.
Such definition help us to understand why some software implementations are so hard o maintain.
Sometimes people don't get it right and make things public when they actually should not. Structures that exposes functionality more than needed, are actually creating a new chance to be coupled to other structures. More coupling means a software that is hard to change . A software that is hard to change is expansive. A software that is expansive... well, you may know what is gonna happen from this point...

The Law of Demeter


It is a Software Design technique that aims  to help create low coupled structures. It's based on the Information Hiding principle where structures know less as possible about each other.  It states that structures should only "talk" with his "close friends" not with strangers. Even when talking with "friends", they should avoid go into "details" about how they internally do things.
As far you manage to create a solution where structures don't know about how internally each other work, you are gonna create a solution that is more susceptible to change. It is certainly a property we look for when creating any software solution.

The problem


To understand the solution, would be better firstly understand the problem. Consider the following:





On the previous example, ClassA has a given responsibility. However, it exposes it's internal details like the ClassB usage. The scenario is even worst once ClassB also exposes the need of use ClassC. This last has actually a functionality that everyone else seems to be interested in. Here everybody knows everybody, this is actually creating a weak dependency chain. As far this system grows, other structures can do the same as ClassA, making the  whole system more coupled and harder to maintain. Here all classes are violating the Demeters's Law. More than that, they don't have good Interfaces.

The Solution


Good interfaces don't reveal its internal implementation details, they expose only what is enough to it's consumers, It provides more flexibility in which regards internal changes once the coupling between structures is well managed. Looking  at the previous solution, it stands out a design flaw once AnotherClass is using ClassC through ClassA and ClassB.
A possible solution would make ClassA manage the calls in a such way that ClassB and ClassC wouldn't need talk to each other. ClassA could also expose the functionality in a such way that AnotherClass wouldn't need to know any other internal structure.




Internal details in all classes are not exposed anymore to AnotherClass. Differently than the previous solution, small internal changes on ClassC are unlikely to break all other classes . The previous chain dependency is now broken into a more composable solution.


Pros

  • Low coupling. A solution that is simpler to maintain 
  • Interfaces that are simpler to use 
  • Improvement on the software testability once internal dependencies are no exposed.

Cons

  • It is common see on the web definitions that the Demeter's Law is a matter of counting the "dots" between method calls (i.e more than two dots violates the law). Look at this direction only can be pointless. Fluent Interfaces is an example that this definition alone can be wrong. The Law should be read as a low coupling principle than other thing. 
  • The Demeter's law issue lives on its own name. It's stated as a law but does not means it never needs to be violated. In cases where the changes on the design aren't worth compared with the benefits, would be ok live with it for a while. A good code/design pratic would help you and your team put a light on this.

Related links: 

No comments:

Post a Comment