Category: Single Responsibility Principle (SRP), Open / Closed Principle (OCP)
This design flaw, inspired by Lieberherr’s Law of Demeter and Martin Fowler’s namesake code smell, refers to the mistake of assuming a given internal structure of classes and explicitly writing navigation code to get from an object to another object stored in its internals in order to use this internal object as prefix in a member reference expression to select the target object for a method invokation or a data access. The name of thid design flaw comes from its typical appearance in code as a chain of references to internal data members, where each reference in the chain targets an internal data member of the object denoted by the previous reference in the chain. A reference to an internal data member is either a direct access to this data member or a call to a method returning this data member. Also, the chain of references can be explicit as shown below:
or implicit, meaning that referenced intermediate data members are stored in local variables, as shown below:
object2 = object1.getDataMember2();
object3 = object2.dataMember3;
Having such chains in a function makes it susceptible to change, whenever the internals of the classes referenced in the chains need to change.
The detection rule for this design flaw looks for a global function or a method containing message chains as the ones described above, involving unassociated objects obtained from at least 3 different data members. An object is considered unassociated with a function (global function or method) if it is not created in that function or for that function using a factory function, it is not passed to the function as parameter, it is not an exception object explicitly caught in the function, it is not a global variable defined in the same file as the global function or meethod, and if applicable it is not a data member or a value returned by a method of the enclosing class or the ancestors of the enclosing class. The severity of this flaw depends on the number of data members used directly or indirectly as prefix in the contained message chains and the number of references (data accesses and operation calls) to these data members.
References: Lieberherr89, Brown98, Fowler99