Assuring Good Style for Object-Oriented Programs.
The language-independent Law of Demeter, which encodes the ideas of encapsulation and modularity in an easy-to-follow form for object-oriented programmers, is presented. The law was developed during the design and implementation of the Demeter system, which provides a high-level interface to class-based, object-oriented systems. Two forms of the law, the class and object forms, are described. Its motivation is to ensure that the software is as modular as possible. Principles covered by the law include coupling control, information hiding, information restriction, information localization, and structured induction. An example is given to show how the law is applied, and valid violations are identified. It is shown how to transform a method that does not satisfy the law into one that does.
Introduction
This paper describes the object-oriented programming style rule called The Law of Demeter.
Along with the 'goto-rule' and other programming style rules inherited from the procedural
programming paradigm, many of which still apply, the Law should be part of the programming
knowledge that is considered when implementing object-oriented software. It is a partial response
to the questions: "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?". In addition, it helps to
formalize the existing ideas on these issues that can be found in the literature [KP86] [Sny87].
There are two kinds of style rules for object-oriented programming: rules that constrain the
structure of classes and rules that constrain the implementation of methods. Style rules that
influence the structure of classes have been published elsewhere [Lie88]. The focus of this
paper is on a style rule that restricts how methods are written for a set of class definitions. In
particular, the Law restricts the message-sending statements in method implementations.
Informally, the Law says that any object receiving a message in a given method must be one
of a restricted set of objects. This set of preferred objects includes the method arguments, the
self pseudo-variable, and to the immediate subparts of self. The self object in Smalltalk and
Flavors is called this in C++ and current in Eiffel.
The Law of Demeter is named after the Demeter System TM , which provides a high-level interface
to class-based object-oriented systems, and the Demeter Research Group at Northeastern
University, which develops the system. The Group has applied the Law in the development of
the system itself (formally about fourteen thousand lines of Lisp/Flavors and now about ninety
thousand lines of C++ code) and in the implementation of numerous applications developed
with the system.
Our experience has been that the Law promotes maintainability and comprehensibility of the
software. This is a result of the small method size and the predicable message-passing patterns,
both of which are caused by the application of the Law. In other words, following the Law in
concert with rules such as, minimizing code duplication, minimizing the number of arguments,
and minimizing the number of methods, produces code with a characteristic and manageable
form.
We have also seen that adherence to the Law prevents programmers from encoding details of
the class hierarchy structure in the methods. This is critical to the goal of making the code
robust with respect to changes in the hierarchy structure. These changes occur very frequently
in the early stages of development.
The goal of the Law of Demeter is to organize and reduce the behavioral dependencies between
classes. Informally, one class behaviorally depends on another class when it calls a method
(through a message sent to an object) defined in the other class. The behavioral dependencies
encoded in the methods of an object-oriented program determine the complexity of the pro-
gram's control flow and the level of coupling between the classes. This paper examines these
relationships and illustrated how the Law impacts their existence.
Some other work describing the Law includes [LHR88] where we presented a proof which states
that any object-oriented program written in bad style can be transformed systematically into
a program obeying the Law of Demeter. The implication of this proof is that the Law of
Demeter does not restrict what a programmer can solve, it only restricts how he or she solves
it. We have also formulated interpretations of the Law for multiple programming languages
[LH89b]. Third party commentary on the Law includes [Boo91, Sak88, Bud91, Gra91]. The
thesis of Casais [Cas90] examines the Law in depth and assesses its favorable impact on the
problem of providing automatic support for rewriting code in response to changes in the class
hierarchy. A slight dissenting voice was raised by Wirfs-Brock et. al [WBW89] who prefer a
function centered approach to object-oriented design rather than the data centered approach
of Demeter.
The examples in this paper are written in the extended notation of the Demeter system.
describes Demeter and its notation. The sections which follow will define the Law of
Demeter both formally and through examples, examining both practical and theoretical issues.
Demeter
The key contribution of the Demeter system is to improve programmer productivity by several
factors. This is achieved in a number of ways. First, Demeter provides a comprehensive
standard library of utilities. Second, a significant amount of code is generated from the programmers
object-oriented design. Third, Demeter includes a number of tools that automate
common programming practices.
The key ideas behind the Demeter system are to use a more expressive class notation than in
existing object-oriented languages and to take advantage of the added information by providing
many custom-made utilities. These utilities are provided for a specific object-oriented language
like C++ or Flavors and greatly simplify the programming task.
Examples of utilities Demeter generates or provides generically are: class definitions in a programming
language, application skeletons, parsers, pretty printers, type checkers, object edi-
tors, re-compilation minimizers, pattern matchers and unifiers. The Demeter system helps the
programmer define the classes (both their structure and functionality) with several support
tools, including a consistency checker (semantic rules and type checking at the design level), a
learning tool which learns class definitions from example object descriptions, an LL(1) corrector
and an application-development plan generator [Lie88] [LR88]. The explanations and examples
presented in this paper are written in the extended Demeter notation which is described below.
One of the primary goals of the Demeter system is to develop an environment that eases the
evolution of a class hierarchy. Such an environment must provide tools for the easy updating of
existing software (the methods or operations defined on the class hierarchy). We are striving to
produce an environment that will let software be 'grown' in a continuous fashion. We believe a
continuous-growth environment will lead to a rapid prototyping/system-updating development
cycle.
The primary input to the system is a collection of class definitions. This collection is called
a class dictionary. Classes are described in Demeter using three kinds of class definitions:
construction, alternation, and repetition. The class dictionary shown in Figure 1 partially
defines the structure of a lending library. 1
1. A construction class definition is used to build a class from a number of other classes and
is of the form
class C has parts
class C
Here C is defined as being made up of n parts (called its instance variable values),
each part has a name (called an instance variable name) followed by a type (called an
instance variable type). This means that for any instance (or member) of class C the name
refers to a member of class SC i
. The example shown in Figure 1 describes a
library class as consisting of a reference section, a loan section, and a journal section.
We use the following naming convention: instance variable names begin with a lower case
letter and class names begin with an upper case letter.
2. An alternation class definition allows us to express a union type. A class definition of the
We use two notations in the Demeter system. This introductory paper uses the extended notation. A
concise notation based on EBNF is used in later papers of the thesis. The abstract syntax of the concise and
the abstract syntax of the extended notation are identical: only the "syntactic sugar" is changed.
class Library has parts
reference
loan
journal
class Library
class BookIdentifier is either
ISBN or LibraryOfCongress
class BookIdentifier
class ReferenceSec has parts
archive : Archive
class ReferenceSec
class Archive has parts
class Archive
class BooksSec has parts
refBooks
class BooksSec
class ListofBooks is list
repeat fBookg
ListofBooks
class Catalog is list
repeat fCatalogEntryg
class Book has parts
class Book

Figure

1: Library class dictionary
class C is either
A or B
class C
states that a member of C is a member of class A or class B (exclusively). For example, the
definition of BookIdentifier in Figure 1, expresses the notion that when somebody refers
to the identifier of a book they are actually referring to its ISBN code or its Library of
Congress code.
3. A repetition class definition is simply a variation of the construction class definition where
all the instance variables have the same type and the programmer does not specify the
number of instance variables involved. The class definition
class C is list
repeat fAg
defines members of C to be lists of zero or more instances of A.
3 Forms of the Law
The Law of Demeter has two basic forms: the object form and the class form. The object form
is the primary form. However, it is not possible to statically check code with respect to the
object form. The two versions of the class form are compile-time checkable approximations.
The two versions of the class form are called the strict form and the minimization form. The
strict version rigorously restricts the dependencies between classes. However, in practice, it is
difficult to completely adhere to the strict version. These potential 'law-breaking' situations
are discussed below. The minimization version is the weakest expression of the Law and is
phrased as a guideline rather than a strict rule. It allows additional dependencies between
classes but asks the object-oriented programmer to minimize them and to document them by
declaring special acquaintance classes.
3.1 Object form
The object version of the Law is based on the concept of preferred supplier objects. These are
defined as follows:
supplier object to a method M is an object to which a
message is sent in M. The preferred supplier objects to method M are:
ffl the immediate parts of self or
ffl the argument objects of M or
ffl the objects which are either objects created directly in M or objects in
global variables.
The programmer determines the granularity of the phrase "immediate subparts" of self for the
application at hand. For example, the immediate parts of a list class are the elements of the
list. The immediate parts of a "regular" class object are the objects stored in its instance
variables.
In theory, every object is a potential supplier to any particular method. When a supplier
object is sent a message in a method, the flow of control passes from the method to a method
implemented for the message receiver. However, the presence of dynamic binding and method
overriding in object-oriented programming languages can make it difficult to statically determine
how control flows from one method to the next. By restricting the set of supplier objects
we can contain the level of difficulty per method.
Object version of the Law of Demeter: Every supplier object
to a method must be a preferred supplier.
The object form expresses the spirit of the basic law and serves as a conceptual guideline
for the programmer to approximate. While the object version of the Law expresses what is
really wanted, it is hard to enforce at compile-time [LHR88]. The object version serves as an
additional guide whenever the strict class version of the Law accepts a program which appears
to be in bad style or when the strict class version of the Law rejects a program which appears
to be in good style.
Client. Method M is a client of method f attached to class C if inside M message f
is sent to an object of class C or to C. If f is specialized in one or more subclasses
then M is only a client of f attached to the highest class in the hierarchy. Method M
is a client of class C if it is a client of some method attached to C.
Supplier. If M is a client of class C then C is a supplier to M. Informally, a supplier
class to a method is a class whose methods are called in the method.
Acquaintance class. A class C1 is an acquaintance class of method M attached to
class C2, if C1 is a supplier to M and C1 is not
ffl the same as C2
ffl a class used in the declaration of an argument of M
ffl a class used in the declaration of an instance variable of C2
Preferred-acquaintance class. A preferred-acquaintance class of method M is
either a class of objects created directly in M or a class used in the declaration of a
global variable used in M.
Preferred-supplier class. Class B is called a preferred supplier to method M
(attached to class C) if B is a supplier to M and one of the following conditions
holds:
ffl B is used in the declaration of an instance variable of C or
ffl B is used in the declaration of an argument of M, including C and its super-
classes, or
ffl B is a preferred acquaintance class of M.

Table

1:
3.2 Class form
The class form's versions are expressed in terms of classes and can be supported by a compile-time
law-enforcement tool. Paralleling the object form, the strict version is based on the notion
of preferred supplier which is defined in table 1.

Figure

shows five examples of massages being sent to objects and of preferred-supplier classes.
To send a message f to object s, we use the C++ notation (s ! f() is the same as "send s the
message f')'. In Figure 2 class B is a preferred supplier to method M and M is a preferred client
of B. The ';' is the comment character which starts a comment line.
class C has parts
implements interface
class C
Case 1: Instance variable class.
class C has parts
none
implements interface
class C
Case 2: Argument class.
class B has parts
none
implements interface
in C++ self is called this
class B
Case 3: Argument class (self).
class C has parts
none
implements interface
newObject is a new B instance
fcalls newObject ! f()g
class C
Case 4: Newly created object class.
class C has parts
none
implements interface
class C
Case 5: Global class. s is global of type B.
In each case, class B is a preferred supplier to M

Figure

2: Examples of preferred suppliers.
As before, every class in an object-oriented program is a potential supplier of any method.
However, it is best to limit the suppliers to a method to a small set of preferred classes. To
define these preferred suppliers we introduce the concept of an acquaintance class of a method
([Sak88], [HB77]). A precise definition of an acquaintance relies on a class version of the
supplier concept. Informally, a method's supplier class is a class whose methods are called in
the method.
The definitions make a distinction between the classes associated with the declaration of the
method and the classes used in the body of the method. The former includes the class where
the method is attached, its superclasses, the classes used in the declarations of the instance
variables and the classes used to declare the arguments of the method. In some sense, these are
an 'automatic' consequence of the method declaration. They can be easily derived from the
code and shown by a browser. All other supplier classes to the method are introduced in the
body of the method. They can only be determined by a careful reading of the implementation.
This second set of classes are the acquaintance classes. To show these classes within a code
browser would require a complete symbol table of the program.
The set of acquaintance classes are further partitioned into a preferred acquaintance subset and
it's complement. A method's preferred acquaintance class is either a class of objects created
directly in the method (by calling the acquaintance class's constructor) or a class used to
declare a global variable used in the method.
Given these definitions, the strict version of the Law of Demeter's class form says:
of the Law of Demeter : Every supplier class to a
method must be a preferred supplier.
There are several benefits which result from applying the strict version of the Law's class form.
For example, if the interface of class A changes, then only the preferred-client methods of class
A and its subclasses require modification (provided that the changes required in the preferred
client methods do not change the interfaces of those classes). A class's interface can change in
many ways. For example, the programmer might modify an interface by changing an argument
or return type, by changing the name of a method, or by adding or deleting a method. A
class's preferred-client methods are usually a small subset of all the methods in a program; this
reduces the set of methods that need to be modified. This benefit clearly shows that the Law
of Demeter limits the repercussions of change.
Using the Law can also control the complexity of programming. For example, a programmer
reading a method needs to be aware of only the functionality of the method's preferred supplier
classes. These preferred suppliers are usually a small subset of the set all the classes in the
application and furthermore, they are "closely related" to the class to which the method is
attached. This relationship makes it easier to remember those classes and their functionality.
The second class version is more lenient than the strict form because it allows some non-preferred
supplier classes. In practice, it makes sense to allow some of these other acquaintance
classes. However, we suggest that the programmer clearly document the violations in order to
recover the Law's benefits. Acquaintance classes are typically used for three reasons:
ffl Stability: If a class is stable and/or if its interface will be kept upwardly compatible, it
makes sense to use it as an acquaintance class in all methods. The programmer specifies
such "global" acquaintance classes separately and they are included in the acquaintance
classes of all methods.
ffl Efficiency: The programmer might need to directly access instance variables of certain
other classes to increase run-time efficiency. In C++ terminology, these are classes of
which the method is a friend function.
ffl Object construction.
The permissive minimization version of the Law of Demeter is stated as follows:
Minimization form of Law of Demeter: Minimize the number
of acquaintance classes of each method.
We can count the number of acquaintance classes for all methods to assess the level of conformance
of a program to the Law. If a class appears as an acquaintance class of several methods,
it is counted as many times as it appears.
If a statically typed language like C++ or Eiffel is extended with a facility to declare acquaintance
classes, the compiler can be modified in a straightforward way to check adherence to
the minimization version in the following sense: Each supplier that is an acquaintance class
must be explicitly declared in the list of the method's acquaintance classes. To easily check
the Law at compile time or even at design time, the programmer must provide the following
documentation for each method:
1. the types of each of the arguments and the result
2. the acquaintance classes.
The documentation gives programmers reading the method a list of the types they must know
about to understand the method. The compiler can check the completeness of each method's
documentation by examining the messages sent in the method and the classes of the objects
created directly by the method.
The motivation behind the Law of Demeter is to ensure that the software is as modular as
possible. The Law effectively reduces the occurrences of certain nested message sends (function
calls) and simplifies the methods.
The Law of Demeter has many implications for widely known software engineering principles.
Our contribution is to condense many of the proven principles of software design into a single
statement that can be easily followed by object-oriented programmers and easily checked at
compile-time.
Principles covered by the Law include:
Coupling control. It is a well-known principle of software design to have minimal coupling
between abstractions (like procedures, modules, methods) [EW88]. The coupling can be
along several links. An important link for methods is the "uses" link (or call/return
link) that is established when one method calls another method. The Law of Demeter
effectively reduces the methods the programmer can call inside a given method and
therefore limits the coupling of methods with respect to the "uses" relation. The Law
therefore facilitates reusability of methods and raises the software's level of abstraction.
Information hiding. The Law of Demeter enforces one kind of information hiding: structure
hiding. In general, the Law prevents a method from directly retrieving a subpart of
an object which lies deep in that object's ``part-of'' hierarchy. Instead, the programmer
must use intermediate methods to traverse the "part-of" hierarchy in controlled small
steps [LG86].
In some object-oriented systems, the programmer can protect some of the instance variables
or methods of a class from outside access by making them private. This important
feature complements the Law to increase modularity but is orthogonal to it. The Law
promotes the idea that the instance variables and methods which are public should be
used in a restricted way.
Information restriction. Our work is related to the work by Parnas et al. [PCW85]
[PCW86] on the modular structure of complex systems. To reduce the cost of software
changes in their operational flight program for the A-7E aircraft they restricted the
use of modules that provide information that is subject to change. We take this point
of view seriously in our object-oriented programming and assume that any class could
change. Therefore, we restrict the use of message sends (function calls) by the Law
of Demeter. Information restriction complements information hiding: Instead of hiding
certain methods, they are made public but their use is restricted. Information restriction
does not offer the same level of protection as information hiding. However, when hiding
it is not feasible, restriction offers a level of protection.
ffl Localization of information. 2 Many software engineering textbooks stress the importance
of localizing information. The Law of Demeter focuses on localizing class information.
When programmers study a method they only have to be aware of types which are very
closely related to the class to which the method is attached. They can effectively be
ignorant (and independent) of the rest of the system. As the saying goes, 'ignorance
is bliss'. This important aspect of the Law helps reduce programming complexity. In
addition, the Law also controls the visibility of message names. Programmers can only
use message names in the interfaces of the preferred-supplier classes to a given method.
ffl Structural induction. The Law of Demeter is related to the fundamental thesis of Denotational
Semantics. That is, "The meaning of a phrase is a function of the meanings of
its immediate constituents". This goes back to Frege's work on the principle of compositionality
in his Begriffsschrift [Hei67]. The main motivation behind the compositionality
principle is that it facilitates structural induction proofs.
5 Example
This section shows how to apply the Law of Demeter to a program that violates both the strict
and the minimization versions of the Law's class form. For this example, we use the classes
defined by the class dictionary fragment for a library shown in Figure 3.
The methods of the example are written in C++. However, the text should be comprehensible
for users of other object-oriented programming languages. In C++ terminology, a method is
called a 'function member' and an instance variable is called a `data member'. In the following
C++ code, the types of data members and function member arguments are pointer types to
classes.
The fragment of a C++ program in Figure 4 searches the reference section for a particular
book. (To keep the example small, we use direct access to instance variables instead of using
access methods.) The searchBadStyle function attached to ReferenceSec passes the message on to
its book (BooksSec), microfiche (MicroficheFiles) and document sections (Documents).
This function breaks the Law of Demeter. The first message marked /*/ sends the message
archMicrofiche to archive which returns an object of type MicroficheFiles. The method next sends
Peter Wegner pointed out this aspect of the Law.
class Library has parts
reference
loan
journal
class Library
class BookIdentifier is either
ISBN or LibraryOfCongress
class BookIdentifier
class ReferenceSec has parts
archive : Archive
class ReferenceSec
class Archive has parts
class Archive
class MicroficheFiles has parts
class MicroficheFiles
class Documents has parts
class Documents
class BooksSec has parts
class BooksSec

Figure

3: Library revisited
this returned object the search message. However, MicroficheFiles is not an instance variable or
argument type of class ReferenceSec.
Because the structure of each classes is clearly defined by the class dictionary, the programmer
might be tempted to accept the method searchBadStyle in Figure 4 as a reasonable solution.
But consider a change to the class dictionary. Assume the library installs new technology and
replaces the microfiche and document sections of the archive with CD-ROMs or Video-Discs:
class Archive has parts
class Archive
class CDRomFile has parts
class CDRomFile
The programmer now has to search all of the methods, including the searchBadStyle method,
for references to an archive with microfiche files. It would be easier to limit the modifications
only to those methods which are attached to class Archive. This is accomplished by rewriting
the methods in good style resulting in searchGoodStyle functions attached to ReferenceSec and
Archive.
Using good style also reduces the coupling respect to the "uses" relation: In the original
class ReferenceSec f
public:
Archive* archive;
boolean searchBadStyle(Book* book) f
return
boolean searchGoodStyle(Book* book) f
return
archive
class Archive f
public:
MicroficheFiles* archMicrofiche;
Documents* archDocs;
boolean searchGoodStyle(Book* book) f
return
class MicroficheFiles f
public:
boolean search(Book* book)
f.g
class Documents f
public:
boolean search(Book* book)
f.g
class Book f.g;

Figure

4: C++ fragment to search the reference section.
version, ReferenceSec was coupled with BooksSec, Archive, MicroficheFiles and Documents, but now
it is coupled only with BooksSec and Archive.
Another way to examine the effects of using the Law is to translate a program, in both good
and bad style, into a dependency graph. In the graphs, the nodes of the graph are classes. An
edge from class A to class B has an integer label which indicates how many calls are written in
the text of the functions of A to the functions of B. If a label is omitted from an edge, it means
that its value is 1. Access to an instance variable is interpreted as a call to read the instance
variable. Figure 5a shows the graph for the program which violates the Law of Demeter; Figure
5b shows the graph for the one that follows the Law.

Figure

5: Dependency graph representation
6 Valid violations
The Law of Demeter is intended to act as a guideline, not as an absolute restriction. The
minimization version of the Law's class form gives programmers a choice of how strongly they
want to follow the Law: The more non-preferred acquaintance classes used, the weaker the
adherence to the strict version. In some situations, the cost of obeying the strict version of the
Law may be greater than the benefits. However, when programmers willingly violate the Law,
they take on the responsibility of declaring the required acquaintance classes. This is critical
documentation for future maintenance of the software.
As an example of where the cost of applying the Law is higher than its benefits, consider the
following prototypical method which is in bad style, coded in both Flavors and C++:
Flavors:
(defmethod (C :M) (p)
C++:
void C::M(D* p)
where p is an instance of class A and F1 returns a subpart of p. If the immediate composition
of A changes the method M may have to change also because of F1.
There are two situations when it is reasonable to leave the above as it is:
ffl F1 is intended to serve as a "black box" and the programmer knows only about the
types of its arguments and the return type. In this case, the maintainer of F1 has the
responsibility to ensure that any updates to F1 are upwardly compatible so programmers
of the function are not penalized for using it.
ffl If run-time efficiency is important to the application, the use of mechanisms such as the
C++ friend function feature may be necessary. Friend functions should be used carefully,
since whenever the private members of a class change, the friend functions of the class
may also require change.
Consider another example that shows where the costs of using the Law might outweigh its
benefits. For an application which solves differential equations the class dictionary may have
the following definitions:
class ComplexNumber has parts
class ComplexNumber
Flavors:
(defmethod (Vector :R) (c :ComplexNumber)
( . (send (send c :realPart) :project self) .))
C++:
void Vector::R(ComplexNumber* c)
The method R is in the same form as M in the previous example and is in bad style for the same
reason. The question here is whether it is important to hide the structure of complex numbers
and to rewrite the method. In this application, where the concept of a complex number is well
defined and well understood, it is unnecessary to rewrite the method so that the Law is obeyed.
In general, if the application concepts are well defined and the classes which implement those
concepts are stable, in the sense that they are very unlikely to change, then such violations as
the above are acceptable.
Our experience has been that writing programs which follow the Law of Demeter decreases
the occurrences of nested message sending and decreases the complexity of the methods, but it
increases the number of methods. The increase in methods is related to the problem outlined
in [LG86] which is that there can be too many operations in a type. In this case the abstraction
may be less comprehensible, and implementation and maintenance are more difficult. There
might also be an increase in the number of arguments passed to some methods.
One way of correcting this problem is to organize all the methods associated with a particular
functional (or algorithmic) task into "Modula-2 like" module structures as outlined in [LR88].
The functional abstraction is no longer a method but a module which will hide the lower-level
methods.
7 Conforming to the Law
Given a method which does not satisfy the Law, how can a programmer transform it so that it
conforms to the Law? In [LHR88] we described an algorithm to transform any object-oriented
program into an equivalent program which satisfies the Law. In other words, we showed that
we can translate any object-oriented program into a "normal form" which satisfies the Law's
strict version.
There are other, less automatic, ways to achieve this goal which may help to derive more
readable or intuitive code. These also may help to minimize the number of arguments passed
to methods and the amount of code duplication. Two such techniques are called lifting and
pushing.
To explain these techniques, we need a preliminary definition. We say that class B is a part-
class of class A, if B is the class of one of A's instance variables or B is a part-class of a class
of one of A's instance variables.
Consider the method:
Flavors:
(defmethod (C :M) ()
(send (send self ':m1) ':m2))
C++:
void C::M()
and T is the class of the object returned by m1. T is not a preferred supplier class of M. We
distinguish two cases:
1. T is a part-class of C.
2. C is a part-class of T.
Lifting. This technique is applicable in the first case (T is a part-class of C). The idea is
to make m1 return an object of an instance variable or argument class of C and adjust m2
accordingly. Method m2 is lifted up in the class hierarchy, from being attached to class T to
being attached to an instance variable class of C.
For example, suppose a program is needed to parse an input using a grammar. A grammar
is made up of a list of rules (productions) indexed by rule name. A fragment of the parse
application is shown in Figure 6. This program fragment uses one acquaintance class (class
Body in the method parse for Grammar).
The problem with the fragment is that method lookUp of Grammar returns an object of class Body
which is not an instance variable class of Grammar. To transform the first method into good
style, we must make the lookUp method return an instance of Rule and then adjust parseDetails.

Figure

7 shows the modified version. The improved program fragment uses no acquaintance
class.
But this lifting approach does not always work, consider Figure 8. This program fragment uses
one acquaintance class (class Rule in method parse of Grammar). Here, we cannot transform the
first method into good style by lifting the return type of the lookUp method.
Pushing. This technique is applicable in cases 1 and 2 (i.e. T is a part class of C and C
is a part class of T respectively). The second case is slightly more complicated as it involves
class Grammar is list
repeat fRuleg
class Rule has parts
class Rule
Flavors:
(defmethod (Grammar :parse) (ruleName :type Symbol)
(send (send self ':lookUp ruleName) ':parseDetails))
(defmethod (Grammar :lookUp) (ruleName :type Symbol)
. (send (send rule ':lookUp ruleName) ':getBody))
(defmethod (Body :parseDetails) ()
.)
C++:
void Grammar::parse(Symbol* ruleName)
f.
return rule
void Body::parseDetails()

Figure

Example code that violates the Law of Demeter
Flavors
(defmethod (Grammar :parse) (ruleName :type Symbol)
(send (send self ':lookUp ruleName) ':parseDetails))
(defmethod (Grammar :lookUp) (ruleName :type Symbol)
. (send rule ':lookUp ruleName))
(defmethod (Rule :parseDetails) ()
.(send self ':getBody) .
C++:
void Grammar::lookUp(Symbol* ruleName)
Rule* Grammar::lookUp(Symbol* ruleName)
f.
return rule ! lookUp(ruleName);g
void Rule::parseDetails()
f. this ! getBody(); .g

Figure

7: New parse implementation
class Grammar has parts
class Grammar
class RuleList is list
repeat fRuleg
RuleList
class Rule has parts
class Rule
Flavors
(defmethod (Grammar :parse) (ruleName :type Symbol)
(send (send-self ':lookUp ruleName) ':parseDetails))
(defmethod (Grammar :lookUp) (ruleName :type Symbol)
returns object of type Rule
(send ruleList ':lookUp ruleName))
(defmethod (RuleList :lookUp) (ruleName :type Symbol)
. )
(defmethod (Rule :parseDetails) ()
. )
C++:
void Grammar::parse(Symbol* ruleName)
Rule* Grammar::lookUp(Symbol* ruleName)
f .
f . g

Figure

8: Law violation that cannot be fixed with the lifting technique.
traveling up the object hierarchy but the general technique is the same as for the first case.
The pushing technique is just a variation of the top-down programming technique of pushing
the responsibility for doing the work to a lower level procedure.
In the lifting example, a problem arose because the Grammar class has the task of sending the
parseDetails message. This task is really the responsibility of class RuleList which knows more
about Rule details than Grammar. Figure 9 shows an improved design that does not use any
acquaintance classes. This is also the technique used in Figure 4 to write searchGoodStyle.
Flavors
(defmethod (Grammar :parse) (ruleName)
(send self ':lookUpParse ruleName))
(defmethod (Grammar :lookUpParse) (ruleName)
(send ruleList ':lookUpParse ruleName))
(defmethod (RuleList :lookUpParse) (ruleName)
(send (send-self ':lookUp ruleName) ':parseDetails))
C++:
void Grammar::parse(Symbol* ruleName)
void Grammar::lookUpParse(Symbol* ruleName)

Figure

9: Example transformed with the pushing technique.
The redesign has introduced an additional method. If list classes are viewed as stable (for
example, as is the case in Smalltalk), there is no need for the redesign and it is justified to keep
the acquaintance class.
8 Conclusion
This paper introduced a simple rule which, when followed, results in the production of structured
and maintainable object-oriented software. The rule, called the "Law of Demeter",
encodes the ideas of data hiding and encapsulation in an easy to follow form for the object-oriented
programmer. The resulting code is more robust, allowing individual classes to be
redesigned while leaving most of the remaining software intact. Furthermore, by effectively
reducing the effects of local changes to a software system, adherence to the Law can reduce
many of the headaches of software maintenance.
But following the Law exacts a price. The greater the level of interface restriction (a refinement
of hiding), the greater the penalties are in terms of the number of methods, execution speed,
number of arguments to methods and sometimes code readability.
But in the long term these are not fatal penalties. We have found that packaging the related
methods and definitions together helps significantly in organizing the increased number
of smaller methods [Lie92]. This facility along with the support of an interactive CASE environment
can erase some of the penalties of following the Law. The Demeter System includes a
formalism, and a code generation mechanism, called Propagation Patterns [LXSL91, LHSLX92]
which removes most of the programming burden of following the Law. This utility generates
major parts of the required code. The execution-speed problem can be countered by using
preprocessor or compiler technologies like in-line code expansion or code optimization similar
to the way tail recursion optimization is done.
In the application of the Law throughout the development of the Demeter System the Law
never prevented us from achieving our algorithmic goals although some the methods needed to
be rewritten. This task was not difficult and the results were generally more satisfying.

Acknowledgements

We would like to thank Gar-Lin Lee for her feedback and contributions
during the development of the ideas in this paper. Thanks also to Jing Na who, along with
Gar-Lin, tested the practicality of using the Law during the production of some of the Demeter
system software. Mitch Wand was instrumental in initiating the investigation into the weak
and strong interpretations. Carl Wolf suggested that the object version of the Law is the one
to be followed conceptually. Special thanks are due to Arthur Riel who was a principal author
on earlier versions of this paper.
Members of the CLOS community (Daniel Bobrow, Richard Gabriel, Jim Kempf, Gregor Kicza-
les, Alan Snyder, etc.) have participated in the debate and/or formulation of the CLOS version
of the Law.
We would like to thank Markku Sakkinen for his interesting paper [Sak88] and his helpful mail
messages about the Law of Demeter. Cindy Brown and Mitch Wand convinced us that we
should use a more readable notation than EBNF and they helped us in designing it. Paul
Steckler and Ignacio Silva-Lepe made several contributions to the extended Demeter notation.
sectionBibliographic Note Earlier reports on the the work described in this paper have appeared
as [LHR88, LH89b, LH89a].



--R


An Introduction to Object-Oriented Programming
Managing class evolution in object-oriented systems
Assessing the quality of abstract data types written in Ada.

Laws for communicating parallel processes.
From Frege to G-odel
A Taste of Smalltalk.
Abstraction and Specification in Program De- velopment
Assuring good style for object-oriented pro- grams
Formulations and Benefits of the Law of Demeter.

Experience with a graph-based propagation pattern programming tool

Component Enhancement: An Adaptive Reusability Mechanism for Groups of Collaborating Classes.
Demeter: A CASE study of software growth through parameterized classes.
Propagation patterns: Graph-based specifications of cooperative behavior
The modular structure of complex systems.
Enhancing reusability with information hiding.
"the Law of Demeter"
Inheritance and the development of encapsulated software systems.

--TR
Abstraction and specification in program development
Inheritance and the development of encapsulated software systems
Demeter: a CASE study of software growth through parameterized classes
Comments on MYAMPERSANDldquo;the law of demeterMYAMPERSANDrdquo; and C++
Object-oriented programming: an objective sense of style

--CTR
Letha H. Etzkorn , Carl G. Davis, Automatically Identifying Reusable OO Legacy Code, Computer, v.30 n.10, p.66-71, October 1997
Fernando Berzal , Juan-Carlos Cubero , Nicolas Marin , Maria-Amparo Vila, Lazy Types: Automating Dynamic Strategy Selection, IEEE Software, v.22 n.5, p.98-106, September 2005
Edward B. Gamble, Jr. , Reid Simmons, The Impact of Autonomy Technology on Spacecraft Software Architecture: A Case Study, IEEE Intelligent Systems, v.13 n.5, p.69-75, September 1998
K. J. Lieberherr , A. J. Riel, Contributions to teaching object-oriented design and programming, ACM SIGPLAN Notices, v.24 n.10, p.11-22, Oct. 1989
Chris Houser, Manual and compiler for the terse and modular language DEM, ACM SIGPLAN Notices, v.31 n.12, p.41-51, Dec. 1996
Yang Liu , Salil Pradhan, The Demeter method: an efficient way to build adaptive software, ACM SIGICE Bulletin, v.22 n.1, p.7-19, July 1996
Nadir Yousfi, Measurement-driven restructuring of object oriented applications, ACM SIGPLAN OOPS Messenger, v.4 n.2, p.175-176, April 1993
Norman Wilde , Paul Matthews , Ross Huitt, Maintaining Object-Oriented Software, IEEE Software, v.10 n.1, p.75-80, January 1993
Karl J. Lieberherr , Ignacio Silva-Lepe , Cun Xiao, Adaptive object-oriented programming using graph-based customization, Communications of the ACM, v.37 n.5, p.94-101, May 1994
Jonathan Aldrich , Craig Chambers , David Notkin, ArchJava: connecting software architecture to implementation, Proceedings of the 24th International Conference on Software Engineering, May 19-25, 2002, Orlando, Florida
Karl Lieberherr , David H. Lorenz , Pengcheng Wu, A case for statically executable advice: checking the law of demeter with AspectJ, Proceedings of the 2nd international conference on Aspect-oriented software development, p.40-49, March 17-21, 2003, Boston, Massachusetts
Adaptive programming in JAsCo, Proceedings of the 4th international conference on Aspect-oriented software development, p.75-86, March 14-18, 2005, Chicago, Illinois
Clark B. Archer , Michael C. Stinson, Object-oriented software product metrics (tutorial), Proceedings of the 1998 ACM SIGCPR conference on Computer personnel research, p.305-306, March 26-28, 1998, Boston, Massachusetts, United States
Korson , John D. McGregor, Understanding object-oriented: a unifying paradigm, Communications of the ACM, v.33 n.9, p.40-60, Sept. 1990
Jilles van Gurp , Jan Bosch, Design erosion: problems and causes, Journal of Systems and Software, v.61 n.2, p.105-119, March 2002
Steve Freeman , Tim Mackinnon , Nat Pryce , Joe Walnes, Mock roles, objects, Companion to the 19th annual ACM SIGPLAN conference on Object-oriented programming systems, languages, and applications, October 24-28, 2004, Vancouver, BC, CANADA
Norman Wilde , Ross Huitt, Maintenance Support for Object-Oriented Programs, IEEE Transactions on Software Engineering, v.18 n.12, p.1038-1044, December 1992
Mira Mezini , Karl Lieberherr, Adaptive plug-and-play components for evolutionary software development, ACM SIGPLAN Notices, v.33 n.10, p.97-116, Oct. 1998
Richard Helm , Ian M. Holland , Dipayan Gangopadhyay, Contracts: specifying behavioral compositions in object-oriented systems, ACM SIGPLAN Notices, v.25 n.10, p.169-180, Oct. 1990
Shahram Javey , Kin'ichi Mitsui , Hiroaki Nakamura , Tsuyoshi Ohira , Kazu Yasuda , Kazushi Kuse , Tsutomu Kamimura , Richard Helm, Architecture of the XL C++ browser, Proceedings of the 1992 conference of the Centre for Advanced Studies on Collaborative research, November 09-12, 1992, Toronto, Ontario, Canada
Martin Hitz , Behzad Montazeri, Chidamber and Kemerer's Metrics Suite: A Measurement Theory Perspective, IEEE Transactions on Software Engineering, v.22 n.4, p.267-271, April 1996
Grel Hedin, Attribute extension - a technique for enforcing programming conventions, Nordic Journal of Computing, v.4 n.1, p.93-122, Spring 1997
Robert V. Binder, Design for testability in object-oriented systems, Communications of the ACM, v.37 n.9, p.87-101, Sept. 1994
Simon Gibbs , Eduardo Casais , Oscar Nierstrasz , X. Pintado , Dennis Tsichritzis, Class management for software communities, Communications of the ACM, v.33 n.9, p.90-103, Sept. 1990
Neville Churcher , Warwick Irwin , Ron Kriz, Visualising class cohesion with virtual worlds, Proceedings of the Asia-Pacific symposium on Information visualisation, p.89-97, January 01, 2003, Adelaide, Australia
Jens Palsberg , Cun Xiao , Karl Lieberherr, Efficient implementation of adaptive software, ACM Transactions on Programming Languages and Systems (TOPLAS), v.17 n.2, p.264-292, March 1995
Tomoyuki Aotani , Hidehiko Masuhara, SCoPE: an AspectJ compiler for supporting user-defined analysis-based pointcuts, Proceedings of the 6th international conference on Aspect-oriented software development, March 12-16, 2007, Vancouver, British Columbia, Canada
Evaluating the Effect of a Delegated versus Centralized Control Style on the Maintainability of Object-Oriented Software, IEEE Transactions on Software Engineering, v.30 n.8, p.521-534, August 2004
K. Lieberherr , C. Xiao, Formal Foundations for Object-Oriented Data Modeling, IEEE Transactions on Knowledge and Data Engineering, v.5 n.3, p.462-478, June 1993
Neville Churcher , Warwick Irwin, Informing the design of pipeline-based software visualisations, proceedings of the 2005 Asia-Pacific symposium on Information visualisation, p.59-68, January 01, 2005, Sydney, Australia
Roger S. Chin , Samuel T. Chanson, Distributed, object-based programming systems, ACM Computing Surveys (CSUR), v.23 n.1, p.91-124, March 1991
K. J. Lieberherr , C. Xiao, Object-Oriented Software Evolution, IEEE Transactions on Software Engineering, v.19 n.4, p.313-343, April 1993
Rebecca J. Wirfs-Brock , Ralph E. Johnson, Surveying current research in object-oriented design, Communications of the ACM, v.33 n.9, p.104-124, Sept. 1990
Karl J. Lieberherr, Controlling the Complexity of Software Designs, Proceedings of the 26th International Conference on Software Engineering, p.2-11, May 23-28, 2004
Karl Lieberherr , Boaz Patt-Shamir , Doug Orleans, Traversals of object structures: Specification and Efficient Implementation, ACM Transactions on Programming Languages and Systems (TOPLAS), v.26 n.2, p.370-412, March 2004
Doug Lea, Christopher Alexander: an introduction for object-oriented designers, ACM SIGSOFT Software Engineering Notes, v.19 n.1, p.39-46, Jan. 1994
Marwan Abi-Antoun , Jonathan Aldrich , Wesley Coelho, A case study in re-engineering to enforce architectural control flow and data sharing, Journal of Systems and Software, v.80 n.2, p.240-264, February, 2007
Antero Taivalsaari, On the notion of inheritance, ACM Computing Surveys (CSUR), v.28 n.3, p.438-479, Sept. 1996
Gary T. Leavens, Introduction to the literature on object-oriented design, programming, and languages, ACM SIGPLAN OOPS Messenger, v.2 n.4, p.40-53, Oct. 1991
modularity;coupling control;object forms;object-oriented programs;law of demeter;structured induction;encapsulation;information restriction;user interfaces;information hiding;object-oriented programming;demeter system;class forms;good style;high-level interface;programming environments;information localization