Architecture logicielle & Développement

The Law of Demeter, part 1/2 | 0 vote(s)

Tags:

Contrary to the French version of this post, I decided to break the English version in two parts. The first part deals with the law formulation, and the second part deals with the application of the law. The reason for that is that it gives me a good reason to continue the translation. I know, that's a strange reason.

In addition to the multiple object oriented software design principles that have been discussed in previous blog tickets, the tool box of the software architect contains many other tools, including a set of "laws".

Of course, these are not law in the juridic meaning of the word. They must be seen as guides whose clever use allows us to simplify the code or the software design. Actually, most of these laws are not fully applied, and they often feature logical restrictions when it comes to their application. As we'll see it later, this is the case of the Law of Demeter.

So, what is this "Law of Demeter"? To know more about it, our first task is to dig history a bit.

The Demeter System

In 1988, Lieberherr, Holland and Riel published an article that presented the result of their work on the Demeter system, a software platform whose goal is to simplify the evolution of class hierarchies. Their basic idea was to try to find a way to evolve a system by incremental changes instead of having to rewrite large portions of it[1]. During their research, they ask themselves: When is an object-oriented program written in good style?, Is there some formula or rule which one can follow in order to write good object-oriented programs?, What metrics can we apply to an object-oriented program to determine if it, is "good"?? and What are the characteristics of good object-oriented programs?.[2]. One of the result of this research is called the Law of Demeter.

Wording of the Law of Demeter

Two different wording has been published by Lieberherr and al. The first one, published in the 1988 article, is considered as imprecise and too restrictive for a large part of the user community. As a consequence, Lieberherr and Holland decided to propose another wording in a 2002 paper[3]. The new wording is more precise, but it's also more complex.

The first important point about the new wording is that it comes with a good number of definitions, whose goal is to define the terms which are used in the wording itself.

Definition: a B-object is an object that belongs the class B

Definition: the protocol of the class C is the set of messages[4] that can be sent to C and to its instances

Exemple : in the code below, a is a B-object ; m1() and m2() are the protocol of B.

struct B
{
  A a;
  void m1();
  void m2();
};

Definition : a method ''uses the protocol of class C' if inside the method a message is sent to a C-object, to C, or if an instance variable of C is accessed or modified.

Definition : method M is a client of class B and B is a supplier of method M, if a B-object or B itself are sent a message in method M or if an instance variable of B is accessed or modified.

Definition : class B is called the potential preferred supplier of method M (attached to class C) if one of the following condition holds:
1) B is an instance variable class of C, or
2) B is an argument class of M, including C, or
3) B is a class of objects created in M (directly or indirectly by calling a method which creates and returns a new object), or
4) B is a class of a global variable used in M

I think I should stop and explain some things here. The first point deals with classes of the C-objects. The second point deals with the class of the method M arguments. Class C is one of these classes - because of the implicit parameter passing of the object itself (this in C++ or C#, self in some other languages). The third point deals with objects that are created in method M - either by an explicit instanciation (object which is created on the heap or on the stack) or by indirect construction (for example, using the factory method or abstract factory design pattern). The last point covers the class of the global variables that can be used in M. All these classes are then collectively called potential prefered supplier.

The corollary of the last definition is quite obvious:

Definition : method M is called a potential preferred client of class B if class B is a potential preferred supplier of method M.

Thanks to this long definition list, we are now able to word the Law of Demeter itself:

Law of Demeter :
In all method M use only the protocol of the potential preferred suppliers classes of M.

Of course, even if you have the whole definition list right in front of you, the law is still a bit cryptic because of its wording. However, it can be simplified - and then you end up with the famous citation of Peter Van Rooijen:

  • You can play with yourself.
  • You can play with your own toys (but you can't break them apart).
  • You can play with toys that were given to you.
  • You can play with toys you've made yourself.
  • and you can play with the community toys[5]

This impertinent wording can be turned into the more software-based:

  • A method of a class B can call other methods of B directly.
  • A method of a class B can call the methods of the member variables of B, but it can't call the methods of the member variables of its member variables.
  • If the method has parameters, it can call the class methods of its parameters
  • If the method creates local objects, it can call their methods as well
  • Finally, the method can call the global variables methods.

Notes

[1] this is where the system name comes from: Demeter is the greek godess of nature - and as a consequence, of plants, which are known to grow up slowly, but surely

[2] K. Lieberherr, I. Holland, A. Riel - Object-Oriented Programming: an Objective Sense of Style, OOPSLA'88 Proceedings; PDF available here

[3] K. Leiberherr, I. Holland - Preventive Maintenance of Objet-Oriented Software; PostScript file available here

[4] in the object terminology, a message is a function that targets an object; in C++, we use the terms "method" or "member function"

[5] this one is not from Van Rooijen, but I had to add it because of the 2002 extension of the law

Trackbacks

Aucun trackback.

Les trackbacks pour ce billet sont fermés.

Commentaires

Aucun commentaire pour le moment.

Ajouter un commentaire

Si votre navigateur est compatible, vous pouvez vous aider de la barre d'outils placée au-dessus de la zone de saisie pour enrichir vos commentaires.