The Law Of Demeter

Featured image

Most of us are familiar (or must be familiar) with the law of Demeter (LoD) as documented here. Basically, the LoD stipulates the principle of least knowledge about the internal structure of your dependencies. Or as in the case of this toilet sign, “no looking at what is happening inside”.

Let us say we have a class A that has a dependency on class B which in turn has a dependency on class C. LoD proscribes constructs of the form b.getC() since these would assume that A has intimate knowledge on the inner workings of B - in this case namely that B has a dependency on C. If B were to change tomorrow to not use C, then the expression b.getC() would not hold good and hence can be a source of code brittleness.

I think the application of LoD must be a little bit different between the data containers and the strategies (as defined here). The data containers as their name implies, just contain data and transport it across different parts of the application. The strategies act on the data and implement various algorithms in accordance with the Strategy pattern.

Data Containers

Data container objects form complex object graphs of inter connected objects. This connection is typically documented as part of the domain model of the application. We can have an Account object for instance that gets attached to a Customer object. These graphs are designed to be navigated by design. This navigational ability indeed forms the core benefit of using the domain model. Hence any class that is cognizant of the domain model, is at liberty to use a construct of the form customer.getAccount() to obtain access to the account object for a customer.

Obviously, a use of this type is contingent upon the documented domain model and is susceptible to break if the domain model changes. This may not be, in itself, a big limitation since the domain model is borne out of an intimate knowledge of the application domain and hence forms a hopefully “rock solid” edifice on which the design rests. If the edifice changes, it would not be surprising that the application is forced to change as well! Hence “knowing the guts” of a domain object or a data container does not seem to be that bad of an idea!

However, as with most things, this statement needs to be caveated by other considerations as well. For instance, the domain model may stipulate a linkage between Customer and Account but may not necessarily suggest a navigable link. In such a situation, a construct of the form customer.getAccount() may be compliant to the domain model but is not necessarily guaranteed  by it. Introducing code that provides for such links may be fraught with peril. Example: If the Customer object in question needs to be cached, should the associated Account object be cached as well? If every Customer object necessarily contains a link to an associated Account object, then caching the former would imply caching the latter.  This may or may not be desirable. Hence the domain model design should cater to these kinds of provisos.

Lazy loading also adds a further twist to this already complicated tale. Let us say Account object is “lazy loaded” as and when customer.getAccount() is invoked. The consumer has to be cognizant of this to avoid unnecessary database (or EAI) invocations.

But, on the whole, knowing the gut of a data container is not very bad. A data container must provide a way to access its inner data to its consumer and a knowledge of that inner data is perhaps more to be desired than to be censured.

Strategies

IMO, LoD is less condoning in case of strategies. A strategy is an encapsulation of an algorithm. The algorithm may in turn utilize other algorithms. To that extent, a strategy may in turn be dependent on another strategy. Example: a persistence strategy may use JDBC for persisting stuff into a database.

But relying on this can be detrimental to the health of the application. Let us say, that we have code in the form

persistenceStrategy.getDBConnection().

This would break if the persistence strategy either changes to not use the database or if it changes to not expose the database connection that it obtained!

So LoD would enforce its cannons more stringently in case of strategies.