Good Object-Oriented Design
- organize and reduce dependencies between classes
Client
-- A method m is a client of C if m calls a method of C
Supplier
-- If m is a client of C then C is a supplier of m
Acquaintance
-- C is an acquaintance of m if C is a supplier of m
but not (the type of) an argument of m or (of) an instance variable
of the object of m
- C is a preferred acquaintance of m if an object of C is created in
m or C is the type of a global variable
- C is a preferred supplier of m if C is a supplier and C
is (the type of) an instance variable, an argument or a preferred acquaintance
slide: Clients, suppliers and acquaintances
In slide [Demeter], an explicit definition of the dual notions
of client and supplier has been given.
It is important to note that not all
of the potential suppliers for a class may
be considered safe.
Potentially unsafe suppliers are distinguished
as acquaintances, of which those that are either
created during a method call or stored in a global
variable are to be preferred.
Although this may not be immediately obvious,
this excludes suppliers that are
accessed in some indirect way, for instance
as the result of a method call to
some safe supplier.
As an example of using an unsafe supplier,
consider the call
screen->cursor()->move();
which instructs the cursor associated with the screen
to move to its home position.
Although screen may be assumed to be a safe supplier,
the object delivered by need
not necessarily be a safe supplier.
In contrast, the call
screen->move_cursor();
does not make use of an indirection
introducing a potentially unsafe supplier.
The guideline concerning the use of safe suppliers is known
as the Law of Demeter, of which the underlying
intuition is that the programmer should not be bothered
by knowledge that is not immediately apparent
from the program text (that is the class interface)
or founded in well-established conventions
(as in the case of using special global variables).
See slide [4-demeter].
Law of Demeter
ignorance is bliss
Do not refer to a class C in a method m unless C is (the type of)
1. an instance variable
2. an argument of m
3. an object created in m
4. a global variable
- Minimize the number of acquaintances!
Class transformations
- lifting -- make structure of the class invisible
- pushing -- push down responsibility
slide: The Law of Demeter
To remedy the use of unsafe suppliers,
two kinds of program transformation are suggested
by [LH89].
First, the structure of a class should be made invisible
for clients, to prohibit the use of a component
as (an unsafe) supplier.
This may require the lifting of primitive actions
to the encompassing object, in order to make these
primitives available to the client in a safe way.
Secondly, the client should not be given
the responsibility of performing
(a sequence of) low-level actions.
For example, moving the cursor should not
be the responsibility of the client of the screen,
but instead of the object representing the screen.
In principle, the client need not be
burdened with detailed knowledge
of the cursor class.
The software engineering principles underlying
the Law of Demeter may be characterized
as representing a compositional approach,
since the law enforces the use of immediate
parts only.
As additional benefits, conformance
to the law results in hiding the component
structure of classes, reduces the coupling of control
and, moreover, promotes reuse by
enforcing the use of localized (type)
information.