Coupling and Cohesion in Object-Oriented Systems
Coupling and Cohesion in Object-Oriented Systems
in Object-Oriented Systems
Johann Eder(1) Gerti Kappel(2) Michael Schre
(3)
(1)
Institut fur Informatik, Universitat Klagenfurt
Universitatsstr. 65, A-9020 Klagenfurt, Austria, email: eder@i.uni-klu.ac.at
(2)
Institut fur Informatik, Universitat Linz
Altenbergerstr. 69, A-4040 Linz, Austria, email: [email protected]
(3)
Institut fur Witschaftsinformatik, Universitat Linz
Altenbergerstr. 69, A-4040 Linz, Austria, email: schre
@dke.uni-linz.ac.at
Abstract
Object-oriented system development is gaining wide attention both in research
environments and in industry. A severe problem encountered, however, is the quic-
kly increasing complexity of such systems and the lack of adequate criteria and
guidelines for \good" designs. To cope with this problem, it is imperative to bet-
ter understand the properties and characteristics of object-oriented systems. In
this paper, we extend the concepts of coupling and cohesion developed initially for
procedure-oriented systems to object-oriented systems. Coupling describes the in-
terdependency between methods and between object classes, respectively. Cohesion
describes the binding of the elements within one method and within one object
class, respectively. We introduce a comprehensive taxonomy of coupling and co-
hesion properties of object-oriented systems and provide guidelines for improving
these properties.
1 Introduction
Building quality systems has been the driving goal of all software engineering eorts within
the last two decades. Among the key qualities a system should support are maintainability,
extendibility, understandability, and reusability [4, 37]. Object-oriented languages and
1
development environments go already a long way in providing features for building such
maintainable, extendible, understandable, and reusable systems. Among the features
which object-oriented languages support are encapsulation and information hiding, user-
dened classes, message passing, inheritance, and polymorphism [46]. Among the features
which development environments support are predened class libraries and application
frameworks, standardized protocols, e.g., naming conventions, and development tools
such as browsers and inspectors [38, 47].
Object-oriented languages and development environments alone, however, are not a pa-
nacea for building object-oriented quality systems. For example, one problem encountered
is the quickly increasing complexity of object-oriented systems, which is due to the many
objects and inter-object relationships in such systems. Hence, what is needed in addition
to an object-oriented language and development environment are guidelines, check lists,
and metrics which help in the design and development of \good" object-oriented systems
- like they were essential for building \good" procedure-oriented systems.
There is an increasing awareness of this problem in the \object community". Se-
veral guidelines and methods for object-oriented system development have emerged in-
dependently, e.g., [1, 20, 22, 23, 28, 31, 50, 57]. Recently, design metrics which take
the idiosyncratic features of object-oriented designs into account have also emerged [2,
9, 10, 18, 19, 41, 42, 43, 54, 55]. A common objective of these design metrics is that
they, besides others, try to quantify the coupling and cohesion properties of the object-
oriented system under investigation. For example, in [55] the authors identify complexity
measures which in
uence coupling and cohesion of object-oriented systems. Besides this
metric-centered view, the notions of coupling and cohesion have been re-discovered in
literature as design characteristics in
uencing properties of object-oriented quality sy-
stems [3, 5, 6, 11, 37, 49, 54]. Coupling and cohesion are the primary attributes that
led to procedure-oriented quality systems [48, 53]. There, coupling is a measure of the
interdependencies between dierent modules, and cohesion is a measure of the binding of
the elements within a single module. To be rated as well-designed, a procedure-oriented
system has to have low coupling properties in terms of few interdependencies between
modules and high cohesion properties in terms of strong bindings between the elements
within a single module. Since those days coupling and cohesion have been adapted to
Ada tasking [45] and abstract data type-based system development [14, 15]. As is stated
in [14], coupling and cohesion signicantly in
uence maintainability, understandability,
and modiability, and thus serve as a guide to the development of quality systems.
Despite of the growing awareness of coupling and cohesion and to the best of our
knowledge, there exists no thorough discussion of coupling and cohesion properties of
object-oriented systems in literature. The goal of this paper is to ll this gap. We intro-
duce a comprehensive taxonomy of coupling and cohesion properties of object-oriented
systems and provide guidelines for improving these properties. We consciously do not try
to quantify the various coupling and cohesion properties besides placing them on some
ordinal scale. This is due to the following reasons. Firstly, we do not try to reinvent
coupling and cohesion properties from scratch but adapt existing research in the area
of procedure-oriented systems and abstract data type-based systems. In that realm, no
quantiable and computable metrics have been investigated. And secondly and most im-
portantly, so far there are no empirical results on the basis of which any coupling and
2
cohesion metric could be veried. Thus, it would not be serious to give numbers with no
experimental backing.
When adapting coupling and cohesion properties from procedure-oriented systems the
following considerations are in place. Firstly, as opposed to procedure-oriented systems
where the module is the only subject of interest, in object-oriented systems there exist
several subjects of interest, such as methods and object classes. Secondly, coupling and
cohesion properties of the various subjects of interest are not independent from each
other. For example, the coupling properties between methods of dierent object classes
highly in
uence the coupling properties between these object classes. The enhancement
of coupling and cohesion concepts for object-oriented systems is the main contribution of
this paper.
The research to be described has been motivated by the project MooD (Methods for
object-oriented Development) together with SIEMENS Austria, one of Austria's major
software development companies. The aim of the project has been to provide a generic
object-oriented software life cycle model, which emphasizes software quality assurance
and reusability [16, 26].
The paper is organized as follows: In the next section we introduce the subjects of
interest in terms of coupling and cohesion characteristics of object-oriented systems. In
Section 3 we analyze coupling quality of various relationships between methods and bet-
ween object classes. Section 4 studies cohesion properties of methods and object classes,
and uncovers interdependencies between coupling and cohesion. Throughout Section 3
and Section 4 we elaborate to which extent existing guidelines improve coupling and
cohesion quality. Section 5 concludes the paper and points to further research.
3 Coupling
Coupling has been dened the rst time in the realm of procedure-oriented systems [53].
Stevens et al. dene coupling as \the measure of the strength of association established
by a connection of one module to another. Strong coupling complicates a system, since a
module is harder to understand, change, or correct by itself if it is highly interrelated by
other modules. Complexity can be reduced by designing systems with the weakest possible
coupling between modules". In the previous section we dened as the object-oriented
equivalent of a module a method. Similar to modules, methods are coupled by invocation
of each other and/or by sharing data. Thus they may have an interaction relationship
with each other (cf. Section 2). Next to methods, also object classes have to be analyzed
in terms of relationships with each other, and thus in terms of coupling properties. Object
classes may have component relationships and inheritance relationships with each other,
in addition to interaction relationships (cf. also Section 2). From these relationships three
dierent dimensions of coupling properties may be deduced in object-oriented systems,
which are:
interaction coupling
component coupling
inheritance coupling
Each of these coupling dimensions induces that the behavior of a class C depends on
the behavior of a class C 0 if C is related to C 0 by one of the relationships mentioned
before. Or, to put it in other words, C has to have some information about C 0 such that
in case C 0 changes, C knows what to change, too. The degree of coupling can be described
as how much, how complex and how explicit this information has to be. On one end
of the scale, low coupling is described by a small, simple and explicit inter-relationship
between methods and between object classes. In general, low coupling correlates to good
software quality in terms of better maintainability and reusability. On the other end,
high coupling is described by a large, complex and implicit inter-relationship making
maintenance a nightmare and reuse even impossible. In the following we study each of
the coupling dimensions in turn.
6
3.1 Interaction Coupling
Methods are coupled by interaction in terms of invocation of each other and/or sharing
of data. Since interaction coupling is most similar to the classical denition of coupling
between modules we adopt the various degrees of classical coupling [53, 59] to describe
interaction coupling. In the following we analyze where interaction coupling in object-
oriented systems diers from the classical notion of coupling. The dierence mainly stems
from two interrelated facts. Firstly, methods belong to object classes. This implies that
object classes may be interaction coupled, too. Secondly, interaction coupled methods
may belong to the same object class. This implies that we have to distinguish interaction
between dierent classes from interaction within a single class.
We consider all degrees of interaction coupling in turn - from worst to best - and
redene them according to the idiosyncracy of object-oriented systems where necessary.
1. content
Content coupling is the worst form of coupling. It means that one method directly
accesses parts of the internal structure, i.e., the implementation of another method.
Thus one method has to know exactly all internals of the other methods, and any
change in one method may in
uence the other.
The object-oriented paradigm in general, and encapsulation and information hiding
in particular prohibit that a method directly accesses the implementation of another
method or hidden instance variables of a dierent class. However, content coupling
may occur if the programmer uses features of some object-oriented languages which
break the information hiding property. For example, the friend option in C++ [13]
allows to access hidden, i.e., private or protected in C++ parlance, instance variables
of dierent object classes.
2. common
Coupling is rated common if methods communicate via an unstructured, global,
shared data space. Common coupling is better than content coupling since all
implicit communication channels are collected in the common area. Nevertheless,
it is still a pathological form of coupling since the number of possible connections
between methods is polynomial, and the locality principle of good software design
is not considered at all.
Encapsulation and information hiding prohibit common coupling. We are also not
aware of any object-oriented language which supports an unstructured, globally
visible data space. We rate coupling based on the use of pool variables in Smalltalk
[17] as external (see below) since these variables provide for a structured, shared
data space with varying visibility.
3. external
External coupling improves common coupling by structuring the global, shared data
space. However, the locality principle is still violated, thus most deciencies of
common coupling remain.
7
Encapsulation and information hiding also prohibit external coupling between me-
thods of dierent classes. Nevertheless, it may occur in object-oriented systems
based on languages which provide globally visible variables. For example, public
instance variables in C++ [13] and Trellis/Owl [51], and pool variables in Smalltalk
[17].
And what happens to methods of the same class? We may nd external coupling
in the interaction between methods of the same class as they may access the same
instance variables which are used similar to global variables in modules. Passing
of data may be implemented through these shared instance variables instead of
using explicit parameters. Note, in general, we do not consider the passing of
information between dierent invocations of methods of the same object in instance
variables as external coupling. That's what instance variables have been invented
for. Coupling is rated as external, however, if instance variables do not represent
the state of the object. Such instance variables contain transient data, i.e., data
which is only relevant during the execution of a method and is not relevant at the
next invocation of a method. Such data may be reinitialized at each invocation
from outside. Transient data should be represented by local variables of the method
and passed to other methods as parameters. Like global data in modules transient
data in instance variables should be avoided. We dene the set of instance variables
of an object class as being minimal if and only if they contain data representing
the (static) state of an object of that class. Methods of such a class cannot be
external coupled to each other. Note, methods of dierent classes, which also do
not inherit from each other, may use public instance variables of these classes for
passing transient data, which is an even worse form of external coupling. Both kinds
of external coupling can and should be avoided.
Example: Consider the denition of an object class EMPLOYEE (note, we assume
that the object classes STRING and DATE have been dened elsewhere):
class EMPLOYEE f
STRING* name; /* all instance variables are private */
STRING* address;
int socialSecurityNumber;
DATE* birthDate;
int age;
DATE* hireDate;
void computeAge (); /* private method */
public;
oat computeSalary ();
g;
void computeAge () f
age = today - birthDate
g;
oat computeSalary () f
...
g;
8
The method computeSalary, which has to know the age of the employee to
compute his or her salary, has to call the private method computeAge before
accessing the instance variable age. Thus, the instance variable age represents
transient data and the calling method is external coupled to the method com-
puteAge. To avoid external coupling computeAge has to return the computed
age as return value to the calling method. 2
For external coupled methods we further distinguish methods and instance variables
implemented at the same class from those implemented at a classes C and a super-
class C 0 of C . We dene the coupling from method m to method m0 as inherited
external
if m implemented at C and m0 dened at C exchange data through instance
variables inherited from C 0 (instead through explicit parameters). This kind
of coupling particularly occurs if the class from which information is inherited
has external coupled methods.
if m implemented at C 00 and m0 dened at C , communicate via public instance
variables inherited by C from C 0, where C 6= C 00 and C is neither a superclass
nor a subclass of C 00.
It is obvious that inherited external coupling between methods is worse than external
coupling between methods as it further complicates maintenance. Since inherited
variables are directly accessed, inherited external coupling not only uses instance
variables to pass transient data but it also breaks encapsulation and information
hiding between an object class and its superclasses [52].
Example: Assume for the example above that the object class EMPLOYEE is a sub-
class of PERSON, from which it inherits the instance variables name, birthDate,
age and the method computeAge. Then the coupling from method computeSa-
lary dened at EMPLOYEE to method computeAge dened at PERSON is rated
inherited external since they communicate via the inherited instance variable
age. Thus the coupling from computeSalary to computeAge is even worse than in
the previous example. 2
4. control
Methods are control coupled if they communicate exclusively via parameter passing,
which implies that they are not content, common, or external coupled, but one
method controls the internal logic of the other method. With control inversion, the
worst form of control coupling, the called method determines the future execution
sequence of the calling method.
Control coupling is not prohibited by object-oriented concepts. Therefore, interac-
tion between methods of the same as well as of dierent classes may be control
coupled. Control coupling should be avoided since the change of the implementa-
tion of a method may cause hidden changes to the behavior of the control coupled
methods. Although control coupling is not prohibited by the object-oriented para-
digm, polymorphism and dynamic binding aid in avoiding control coupling. Instead
9
of passing a
ag which controls method execution, polymorphism and dynamic bin-
ding can be employed.
5. stamp
Two methods are stamp coupled if, in analogy to classical coupling, they are not
control coupled but whole data structures are passed as parameters although only
parts of the data structure would suce. The essence of stamp coupling is as follows:
a method depends on some externally dened data structure and has to be changed
if this data structure changes, although the change would otherwise not in
uence
the method. Stamp coupling has to be rephrased for object-oriented systems since
there exist two kinds of stamp coupling.
The rst kind of stamp coupling is similar to the classical denition of stamp cou-
pling. According to that denition, a method depends on the domain of its pa-
rameters. The domain of a parameter may either be an object class, or a basic
data type, or a complex data type based on type constructors such as tuple, array,
and set. Depending on the domain of the parameter, either basic data values, or
complex data values, or objects may be passed as parameters. If a complex data
value is passed as parameter stamp coupling occurs if already parts of the complex
data value would suce. This case is analogous to the classical denition of stamp
coupling. If objects are passed as parameters a similar problem may occur. We
recall that an object may again consist of (references to) other objects. Such an ob-
ject is also called composite object since it is constructed out of component objects.
Thus we have to investigate the question whether the object passed as parameter
or merely some of its components are relevant for a method. If an object is passed,
and the method uses just some of the object's components but not the object itself,
we classify this interaction as stamp coupled. If the object passed as parameter is
used as a whole, we call it data coupling (see below).
To improve stamp coupling to data coupling an object should be replaced by its
components whenever possible, in particular, if only some but not all of its compo-
nents are necessary. Note, that there are rare cases where the replacement of an
object by its components may leave extensibility more dicult. Such a situation
occurs if only some components of an object are currently needed by some method
m but the object is extended with an additional component in the future and this
component is also requested by m. If the object would have been passed as para-
meter no change of the interface of m would have been necessary. However, there
exist other solutions without the above mentioned problem. For example, adding a
new method with the appropriate parameters is just one possible solution.
Example: Consider the class EMPLOYEE as dened above with the additional in-
stance variable sales, and another object class SALES-STATISTICS with the in-
stance variable accummulatedSales, and the method addSale with the input para-
meter being an employee object. However, the method addSale should not take
an employee object as parameter, which leads to stamp coupling, but the value
of the relevant instance variable sales of a particular employee, which would
lead to data coupling. 2
10
The second kind of stamp coupling uncovers dependencies between a method and the
domain of instance variables of the same class. The denition of instance variables
is external for a method. At rst sight it may look strange to consider interaction
between methods and instance variables. However, it leads to rules for a better
organization of methods. The value of an instance variable is either a basic data
value, or a complex data value, or a reference to some object depending on the
domain of the instance variable. If a method directly accesses an instance variable
although it needs only parts of its value, the method has to be changed if the domain
of this instance variable is changed, e.g., due to optimization purposes.
The key idea for improving this kind of stamp coupling is to distinguish between
methods which directly access instance variables, i.e., the internal data structure
of a class, and methods which do not. It is good design to hide the internal data
structure whenever possible { not only from the outside of an object class but
also from methods inside of the object class. Therefore, we suggest to design read
methods and write methods, called access methods, for each instance variable and
use these methods as only means to access these variables. If the internal data
structure of an object class is changed only the access methods have to be updated,
too.
Example: Consider the class MATRIX with the methods accessElement and multipli-
cation. The coupling between the method multiplication and the implementation
of the matrix's data structure is lower if the method accesses the elements of
the matrix by the access operation accessElement, and it is higher if multiplication
directly accesses the instance variables. Considering the former, if the repre-
sentation of the matrix is changed, e.g., for sparse matrices, only the access
methods have to be changed but not the multiplication method. 2
The idea of restricting the access to instance variables via explicit access methods
is not new. It has already been advocated as important object-oriented design
guideline [23, 57], and it is realized in some object-oriented languages, such as
Trellis/Owl [51]. Note, that there exist design rules in the area of software reuse [40]
leading to a factoring out of methods from some object class if they do not directly
access instance variables of that class. This might increase, however, interaction
coupling between classes. Thus there is some trade-o between various design goals
and the designer has to decide which goal to prefer on a case by case basis.
Here again we have to take inheritance of methods and instance variables into ac-
count. Stamp coupling between a method and inherited instance variables is called
inherited stamp coupling. It is worse than stamp coupling between a method and
instance variables dened within the same class. This is due to the commonly accep-
ted understanding that directly accessing inherited instance variables in subclasses
breaks encapsulation and information hiding [52].
6. data
Two methods are data coupled if they communicate only by parameters and these
parameters are relevant as a whole. Data coupling is the best form of coupling
11
whenever two methods have to interact. Data coupled methods minimize main-
tenance eort due to a great restriction of change propagations.
7. no direct coupling
The theoretical optimum of interaction coupling is no direct coupling, i.e., two
methods do not (directly) depend on each other, and thus also their object classes
are not interaction coupled. A change in one method does not directly demand a
change in the other method, and hence no change in that method's object class is
necessary.
primitives in Smalltalk like integers and booleans are also object classes practically every
class is component coupled to primitives. However, since primitives are very stable one
shouldn't care too much that an object class is component coupled and thus dependent
on primitives.
Of course, component coupling usually implies interaction coupling. In interaction
coupling, however, we focused on how much information is exchanged between methods
and classes, respectively, and on how complex this information is. With component cou-
pling we will analyze how explicit the coupling between classes is.
The rst case of component relationship given above is realized via instance variables.
It is made explicit in object-oriented languages at the class level, but only in the imple-
mentation part and not in the specication part of a class denition. Coupling of the
1 We are grateful to David Monarchi who pointed this out to us.
12
second case is made explicit in the specication part of a class denition by specifying
the signatures of the methods. Component coupling of the third case is based on local
variables. It is only explicit within a method through the declaration of local variables
but it is not explicit at the class level. The fourth case is even worse. For example, in
cascading messages, the object returned by a method is used immediately as receiver of
another message. The object class of this receiver might not even be declared anywhere
in the actual class.
Based on these considerations we dene the following degrees of component coupling
from worst (highest) to best (lowest).
1. hidden
The coupling between two classes C and C 0 is rated hidden if C 0 shows up neither
in the specication nor in the implementation of C , although an object of C 0 is used
in the implementation of a method of C .
To give examples of situations where hidden coupling is likely to occur we refer to
the cascading message problem stated above. A similar problem is encountered if
the return value of a method invocation is immediately used as input parameter in
another method invocation. Most languages do not require that the class of this
object is declared anywhere within the actual class.
Hidden coupling causes problems since this coupling between classes is implicit.
We compare hidden coupling with the use of global variables in procedure-oriented
systems, which is responsible for common coupling between modules. Consider a
change of a class in a maintenance process, e.g., the change of the signature of a
method. In the presence of hidden coupling the programmer has to search through
all implementations of all methods of all classes to detect where this change may
have in
uence, and where this change has to be propagated to, respectively.
A possibility to avoid hidden coupling is to disallow the use of cascading messages,
for example, suggested implicitly by the Law of Demeter [30, 31], and to disallow
the use of return values as parameters if their domains are not declared. A less
restrictive way to overcome hidden coupling is to declare all those classes in the
specication part of the actual class denition.
Example: Consider the class EMPLOYEE as dened above with the additional in-
stance variable involvedInProject, which references the project for which an em-
ployee is currently working, and the additional method numberColleagues, which
returns the number of colleagues in the current project. The implementation
of numberColleagues may be given as follows:
int numberColleagues () f
return (involvedInProject->getProjectMembers->count - 1)
g
14
Example: In the previous example the classes EMPLOYEE and SEThEMPLOYEE*i
are scattered coupled. We may improve their coupling property to specied
coupling by changing the specication of EMPLOYEE as follows:
class EMPLOYEE f
suered interface: /* corresponds to public in C++ */
int computeSalary ();
int numberColleagues ();
...
required interface: /* not available in C++ */
SEThEMPLOYEE*i* class PROJECT::getProjectMembers ();
int class SEThEMPLOYEE*i::count ();
...
g;
2
There exist several object-oriented specication languages which provide mecha-
nisms to specify the required interface, e.g., collaborators in [58], uses relationship
in [5, 21], calling relationships in [24], and invocation diagrams in [25]. However,
we know of only one object-oriented language, Modula-3 [8], which supports sue-
red and required interface specications by export and import declarations at the
module level.
4. nil
The theoretical optimum is no direct component coupling between classes and thus
no interaction coupling. It is an advantage to recognize that two classes are com-
pletely independent such that one class can be maintained without any knowledge
of the other class.
15
coupling (besides no coupling) coincides with better reusability. Furthermore, conside-
ring inheritance coupling is necessary for improving the overall quality of the system to
be implemented. Since it is possible to gain good interaction and component coupling
properties by sacricing the quality of the inheritance hierarchy, inheritance coupling has
to be considered, too.
Inheritance coupling is also dierent from interaction coupling and component coupling
in that it does not only exhibit the coupling property between subclasses and superclasses
but implicitly also the coupling property between an interaction coupled object class
and the inheritance hierarchy. The meaning is the following: if class D is interaction
coupled to some class C being the root of an inheritance hierarchy and the inheritance
hierarchy is changed, e.g., subclasses are added, and inherited instance variables and
methods are modied, the degree of inheritance coupling reveals to which extent changes
in the inheritance hierarchy might impose changes in D (for a detailed discussion of the
interdependencies of the various coupling dimensions see Section 3.4).
In the following we discuss the various degrees of inheritance coupling from worst
(highest) to best (lowest). Note, we assume for simplicity and without loss of generality
that access methods for each instance variable exist. Thus any change to an instance
variable in some subclass is re
ected by the corresponding change of the signature and/or
implementation of the access methods.
1. modication
Modication coupling is the worst case of inheritance coupling since in addition
to dening new information the inherited information is changed arbitrarily or is
even deleted. Depending on the kind of modication we further distinguish between
signature modication and implementation modication:
(a) signature modication
The coupling between subclass C 0 and superclass C is rated signature modi-
cation if not only the implementation but also the signature of an inherited
method is changed without any restriction, or inherited methods are deleted in
C 0. The relationship between C 0 and C is a pure implementation relationship,
i.e., the use of inheritance is solely for code reuse. An inheritance hierarchy
based on signature modication is dicult to maintain and to extend since it
soon may become very complex. What counts even worse is the fact that it
impairs polymorphism and strong typing in interaction related classes. Assume
class D which invokes a method m on an object of class C . Assume further-
more that the signature of m is changed in subclass C 0 of C arbitrarily. Due
to polymorphic variables it might happen at run-time that D invokes m on an
object of class C 0. This object, however, assumes another invocation of m due
to signature modication and issues a run-time type error. We conclude that
inheritance coupling based on signature modication should be avoided in any
case.
If only a part of the class denition of class C is to be used in class C 0 the two
classes should not be inheritance coupled but C 0 should be component coupled
16
to C via an instance variable of C 0 with the domain of the instance variable
being class C .
Example: Consider class STACK inheriting from class ARRAY. Since ARRAY
is only used to implement STACK's internal data structure, and since the
methods of ARRAY are semantically not meaningful when used with a stack
(e.g., the method putAt of ARRAY does not exist for a stack) the methods of
ARRAY are only inherited for private use but are deleted from the suered,
i.e., public interface of STACK. Thus STACK and ARRAY are signature modi-
cation coupled. To improve their coupling the denition of STACK should
include an instance variable a with domain ARRAY instead of inheriting
from ARRAY. 2
(b) implementation modication
The coupling between subclass C 0 and superclass C is rated implementation
modication if the implementation of an inherited method is changed without
any restriction. This degree of inheritance coupling is better than the previous
one since neither the signature of a method is changed arbitrarily nor are
methods deleted. Nevertheless, implementation modication coupling should
also be avoided since the semantics of a method may be changed completely in
subclasses, and thus the semantics of methods invoking the inherited method
may be changed implicitly, too.
2. renement
Renement coupling is much better than modication coupling since in addition to
dening new information the inherited information is only changed due to predened
rules. Depending on the kind of renement we further distinguish between signature
renement and implementation renement:
(a) signature renement
The coupling between subclass C 0 and superclass C is rated signature re-
nement if they are not modication coupled and if the signature of at least
one inherited method m is changed in C 0 due to some predened rule without
changing the intended semantics of m. Signature renement may adhere to
the covariant rule or to the contravariant rule [7, 34] of subclassing. In the
covariant rule, domains of input parameters and of the return value may be
replaced by subclasses. In the contravariant rule, domains of input parameters
may be replaced by superclasses and the domain of the return value may be
replaced by a subclass. In general, signature renement based on the covariant
style should be avoided since it may also break polymorphism and strong ty-
ping in interaction related classes [34]. However, there are situations where the
semantics of the problem domain is best described in terms of inheritance ba-
sed on the covariant style. In such situations the polymorphic use of variables
and methods should be avoided to avoid run-time type errors.
Example: Consider parts of the denition of object class PERSON and of
subclass EMPLOYEE of PERSON:
17
class PERSON f
[0..120] age; /* for simplicity we assume */
... /* the existence of an enumeration type [0..120] */
public; /* and [15..65] */
[0..120] getAge ();
void setAge ([0..120] a);
...
g
Since employees may only be active from 15 to 65 (at least in Austria) the
subclass EMPLOYEE of class PERSON renes the signatures of the inherited
access operations of age according to the covariant style. Thus, EMPLOYEE
and PERSON are signature renement coupled based on the covariant style.
2
(b) implementation renement
The coupling between subclass C 0 and superclass C is rated implementation
renement if the signatures of the inherited methods are not changed at all,
and the implementation of at least one inherited method m is changed in C 0
due to some predened rules such that the intended semantics of m is kept.
This kind of inheritance coupling might become necessary if the implemen-
tation of an inherited method has to be rened in some subclass. Language
features which support implementation renement are, for example, SUPER of
the language Smalltalk [17], inner of the language Beta [29], and before and
after daemons of the language CLOS [27]. SUPER is used in the changed im-
plementation of an inherited method to invoke the method's implementation
dened in the superclass. Whereas the concept SUPER does not enforce imple-
mentation renement the inner concept and the before and after daemons do
enforce it. inner is used in the original implementation of some method m to
specify the place in the code where a future renement of m has to be placed by
the compiler. Thus, if m is invoked on an object of some subclass not only the
most rened code but also the code dened in the superclasses gets executed.
Similar holds true for before and after daemons. As the name already suggests,
they may be specied in subclasses to rene the implementation of m given
in some superclass. If m is invoked on an object of some subclass all before
daemons get executed up to the original implementation of m and before the
original implementation is executed. After the original implementation has
been executed all after daemons get executed in the reverse order of the before
18
daemons.
Note, there exist object-oriented languages, such as Eiel [39], where it is possible
to change the implementation of a method arbitrarily, and at the same time to
rene the signature of the same or another method. These languages exhibit both
implementation modication coupling and signature renement coupling.
3. extension
Inheritance coupling between a subclass and its superclass is rated extension coupled
if the subclass only adds methods and instance variables but neither modies nor
renes any of the inherited ones. Extension coupling is the best kind of inheritance
coupling (besides no inheritance coupling at all). Extension coupling is achieved if
the superclass is semantically a generalization of its subclasses and the methods of
the superclass can be invoked on objects of the subclasses without inspecting the
(intermediate) subclasses.
Example: Assume that EMPLOYEE is an extension coupled subclass of PERSON.
Then, all methods dened at PERSON can be used for employee objects wi-
thout checking whether they have been modied or rened in the denition of
EMPLOYEE. 2
4. nil
If there is no inheritance relationship between two classes their inheritance coupling
is rated nil.
B’ B’’ C’
m_B { m_C
...
m_C’
}
invokes
subClassOf
20
From { To Predicates & Derivations
implements(A; m A)
implements(B; m B )
implements(C; m C )
implements(B 00; m B )
implements(C 0; m C )
implements(C 0; m C 0)
A?B invokes(A; m A; B; m B )
B?C invokes(B; m B; C; m C )
B0 ? B isa(B 0; B )
B 00 ? B isa(B 00; B )
B 00 ? C 0 invokes(B 00; m B; C 0; m C 0)
C0 ? C isa(C 0; C )
A?B invokes(A; m A; B; m B ) ^ implements(B; m B ) ^ isa (B; B ) =)
icw(A; m A; B; m B )
B?C invokes(B; m B; C; m C ) ^ implements(C; m C ) ^ isa (C; C ) =)
icw(B; m B; C; m C )
B 00 ? C 0 invokes(B ; m B; C 0; m C 0) ^ implements(C 0; m C 0) ^ isa (C 0; C 0) =)
00
icw(B 00; m B; C 0; m C 0)
A ? B0 no coupling
A ? B 00 invokes(A; m A; B; m B ) ^ isa (B 00; B ) ^ implements(B 00; m B ) =)
icw(A; m A; B 00; m B )
B ? C0 invokes(B; m B; C; m C ) ^ isa (C 0; C ) ^ implements(C 0; m C ) =)
icw(B; m B; C 0; m C )
B0 ? C no coupling
B0 ? C 0 no coupling
B 00 ? C no coupling
A?C icw(A; m A; B; m B ) ^ icw(B; m B; C; m C ) =) icw(A; m A; C; m C )
A ? C0 1. icw(A; m A; B 00; m B ) ^ icw(B 00; m B; C 0; m C ) =)
icw(A; m A; C 0; m C 0)
2. icw(A; m A; B; m B ) ^ icw(B; m B; C 0; m C ) =)
icw(A; m A; C 0; m C )
Table 1: Coupling predicates
We do not discuss each entry in Table 1 but restrict our attention to the most in-
teresting one, the derived coupling between A and C 0. It reveals that A is interaction
coupled with C 0 via method m A following dierent invocation paths and thus invoking
dierent methods on C 0. On one hand, A is interaction coupled with C 0 via B and B 00.
This case occurs when m A invokes m B on a member object of B 00. As a consequence,
the implementation of m B at class B 00 gets executed which invokes the method m C 0 of
class C 0 in turn. On the other hand, A is interaction coupled with C 0 via B and C . That
case occurs when m A invokes m B on an instance of B which in turn invokes m C on
a member object of C 0. Since m C is redened at C 0 the implementation of m C given
at class C 0 gets executed. The lessons learned from this example are twofold. Firstly,
the transitive closure of interaction coupling and inheritance coupling together leads to a
complex graph where it is not obvious at rst sight which object classes are interaction
21
coupled with each other. Secondly, due to overriding and polymorphic variables it may
occur that there exist several dierent invocation paths between two methods. Thus the
same two objects of two classes may exhibit dierent run-time behavior at dierent times
although initially the same method is invoked.
Summarizing, it is very important to conduct a global analysis of the classes of an
object-oriented system in terms of coupling properties whenever possible since it may
reveal hidden couplings which may cause problems when maintaining or extending the
system at hand.
4 Cohesion
Cohesion has been dened in the realm of procedure-oriented systems [53] as \the degree
of connectivity among the elements of a single module". Cohesion has been recognized
as one of the most important software quality criteria. Modules with strong cohesion, in
particular with functional cohesion, are easier to maintain, and furthermore, they greatly
improve the possibility for reuse. A module has strong cohesion if it represents exactly one
task of the problem domain, and all its elements contribute to this single task. Elements
of a module are statements, subfunctions, and possibly other modules. We recall that
the object-oriented counterparts of a module are methods and classes. The elements of a
method are statements, local variables, and also instance variables since they are accessed
either directly or via access functions in the methods. Next to methods also object classes
have to be analyzed. The elements of an object class are methods and instance variables.
Thus we have to distinguish the cohesion of a method from the cohesion of an object
class. For the latter, we further distinguish the cohesiveness between elements directly
dened within the same class from the cohesiveness between inherited and directly dened
elements. Thus the following kinds of cohesion may be dened for object-oriented systems:
method cohesion
class cohesion
inheritance cohesion
In the sequel we study each of the cohesion relationships in turn.
2
3. non-delegated
The cohesion of a class is rated non-delegated if it is neither separable nor multifa-
ceted and if one method uses instance variables which describe only a component of
the respective class. Hence, we may again use data normalization theory to detect
non-delegated cohesion like we did for the analysis of multifaceted cohesion. For
this purpose, we also adapt the denition of non-delegated cohesion as follows. The
cohesion of an object class is rated non-delegated if the set of instance variables
interpreted as relation schema is not in third normal form. To put it in other words,
there exist instance variables which do not describe the whole data abstraction re-
presented by the class but only a component of it. To overcome non-delegated
cohesion the \non delegated" methods and instance variables should be delegated
to the component classes on which they are actually dened.
Example: Consider again the object class EMPLOYEE:
class EMPLOYEE f
STRING* name;
DATE* birthDate;
PROJECT* involvedInProject;
EMPLOYEE* managerOfProject;
...
public:
oat computeSalary ();
bool managerIncomeHigherThanAverageInProject ();
...
g;
26
SEThEMPLOYEE*i* membersOfProject;
DATE* startDate;
DATE* expectedEndDate;
...
public:
bool managerIncomeHigherThanAverageInProject ();
SEThEMPLOYEE*i* getProjectMembers ();
...
g;
2
Unfortunately, it is not always as obvious as in the example above where to place
methods. The placement of methods also raises several questions concerning the
visibility and the possible invocation of methods. If a method is delegated to a
component class because it mainly uses instance variables of that component class we
have to consider if and how this method is visible to clients of the inspected class, i.e.,
the class under consideration. One way to organize the invocation of the delegated
method is that clients of the inspected class receive a handle to the component
object, thus, they are able to directly invoke the method on the component object.
This solution might not always be desirable since it means that the inspected class
exhibits parts of its implementation, i.e., its components. Furthermore, this solution
may increase the number of classes the clients of the inspected class have to interact
with. Thus the component coupling between a client class and the component class
may be made worse.
Another possibility to organize the invocation of the components' methods is to hide
the component structure completely from the client classes and to let them access
the methods of the component classes through so called propagation methods of
the inspected class. This solution is recommended by the Law of Demeter from
Lieberherr et al. [30, 31, 32, 33]. The law states that a method m of some class
C may only invoke methods of such classes which are used as domains of instance
variables of C , or as domains of input parameters of m. Objects which are newly
created within m may also be the receivers of messages. Essentially, the law prohi-
bits method invocation on objects which have been returned by some other method.
One goal of the Law of Demeter is to decrease the coupling between dierent object
classes by restricting the object classes with which a specic class may commu-
nicate. However, the decrease of component coupling is traded for an increase of
interaction coupling between the client classes and the inspected class and between
the inspected class and the component class, respectively. For each method of the
component class which should be visible to the client class a propagation method
has to be implemented at the inspected class. The client class calls the propaga-
tion method, which calls the corresponding method in the component class in turn.
Besides the increase of interaction coupling, propagation methods also introduce
tramp data, i.e., data which is passed from the client class via the inspected class
to the component class without being used in the inspected class at all. Tramp
data increases interaction coupling between the client class and the inspected class
27
since a change of the denition of this data implies a change of the inspected class
although the data is not used.
At rst sight there exists a contradiction between the Law of Demeter and the
goal to avoid non-delegated cohesion. Whereas the former introduces propagation
methods, i.e., non-delegated methods, to reduce component coupling, the latter
factors out non-delegated methods to component classes to increase class cohesion
and { as side-eect { to reduce interaction coupling. A solution to overcome this
dilemma is to consider the situation from a semantic point of view. If the component
structure describes a relationship between conceptually dierent objects, as revealed
by semantic data modeling, it is favorable to reveal the component hierarchy in order
to avoid propagation methods with tramp data. But, if the component structure
is mainly an implementation detail, the solution with propagation methods is more
appropriate.
4. concealed
The cohesion of a class is rated concealed if it neither has separable, nor multifaceted,
nor non-delegated cohesion, but there exists some useful data abstraction concealed
in the data abstraction represented by the class. In modules, concealed cohesion
resembles a piece of inline code which can be factored out to a subroutine or function.
In analogy, a class with concealed cohesion includes some instances variables and
referencing methods which may be regarded as a class of its own. Factoring out of
such parts has two advantages. Firstly, the structure of the inspected class becomes
more intuitive and more concise, thus increasing the class' cohesion. Secondly, it
permits the new class being reused as component in other classes as well.
Factoring out such a concealed class implies that the instance variables factored out
are replaced by one instance variable referencing an object of the new class. All
methods of the inspected class referencing only factored out instance variables are
factored out, too. For some methods, one has to decide whether to place them in
the new class or to leave them in the inspected class according to the discussion
above about non-delegated cohesion.
Example: Consider again the object class EMPLOYEE with the instance variables
name, jobProle, dayOfBirth, monthOfBirth, and yearOfBirth, and dayOfHire, mon-
thOfHire and yearOfHire. The instance variables describing various dates may
be factored out to a new class DATE with the instance variables day, month,
and year. The respective instance variables of the class EMPLOYEE are then
replaced by two instance variables birthDate and hireDate. 2
Candidates for new classes are on one hand instance variables with complex domains,
and on the other hand sets of instance variables which are often used together in
methods but rarely used together with other instance variables. Some kind of cluster
analysis may exhibit candidates. When creating a new class we have to keep in mind
that the class should have the best cohesion characteristic possible.
5. model
28
Model cohesion is the highest degree in our classication. The cohesion of a class
is rated model if the class represents a single, semantically meaningful concept
without containing methods which should be delegated to other classes and without
containing concealed classes.
It is interesting to note that a semantically similar notion, informational strength,
has been already dened by Myers [44] in the realm of module-oriented systems.
There, a module is interpreted as implementation of an abstract data type. Taking
the classical function-oriented notion of cohesion a bit further Myers denes a mo-
dule to have informational strength if all its functions have functional cohesion and
they work on the same set of data.
5 Outlook
In this paper we introduced a comprehensive taxonomy of coupling and cohesion charac-
teristics of object-oriented systems. In contrast to the classical notion of coupling and
cohesion being based on a single concept, the module, there are two subjects of inter-
est, methods and object classes, in the realm of object-oriented systems. In addition,
the important concept of inheritance considerably in
uencing the structure of an object-
oriented system has to be taken into account. This leads to three interrelated dimensions
of coupling and cohesion, respectively: interaction coupling, component coupling, and in-
heritance coupling, as well as method cohesion, class cohesion, and inheritance cohesion.
The goal of the paper has been to dene qualitative criteria for coupling and cohesion
to improve the quality of object-oriented systems. The paper deliberately did not aim
at metrics and quantitative criteria. The reason is not at all that these aspects are not
important. However, it is our rm belief that at the current state of art of object-oriented
quality assessment it is very important to uncover the various aspects of quality criteria.
Once these criteria are commonly accepted, metrics and automatic quality assessors may
be developed. Furthermore, the paper deals only with coupling and cohesion properties.
Software quality, however, does not depend exclusively on these two properties but on
29
various other factors like method fan-in/fan-out, and reuse via inheritance and polymor-
phism, to mention just a few. To reach a comprehensive assessment of software quality all
factors have to be considered. In case of con
icting goals individual, problem dependent
decisions have to be taken. Finally, we did not take any performance considerations into
account when dening the various degrees of coupling and cohesion. The reason is that
coupling and cohesion are criteria for evaluating object-oriented designs in the rst place.
The designs may be tuned during implementation for performance reasons.
Further research expands mainly into three areas. Firstly, a comprehensive analysis of
existing object-oriented design guidelines concerning their in
uence on coupling and cohe-
sion quality will help in unifying and consolidating the various approaches to good designs.
Secondly, as soon as a common understanding of coupling and cohesion characteristics
is reached tools for (partially) automatic assessment of coupling and cohesion properties
will be developed. There is some condence that these tools not only aid in designing
good object-oriented software but are a useful means when searching class libraries and
identifying related object classes [36]. Lastly, the long-term goal comprises the investiga-
tion of other quality criteria of object-oriented systems and their interdependencies with
the coupling and cohesion characteristics dened in this paper.
Acknowledgement
The authors are grateful to Dieter Merkl, Roland Mittermeir, David Monarchi, Georg
Reichwein, and Markku Sakkinen for valuable comments on earlier versions of this paper.
References
[1] E. Andono, \Normalization of Object-Oriented Conceptual Schemes," in Procee-
dings of the Conference on Advanced Information Systems Engineering (CAiSE'93)
, ed. C. Rolland, F. Bodart and C. Cauvet, pp. 449-462, Springer LNCS 685, 1993.
[2] S.C. Bailin, \An automated quality assessor for Ada object-oriented designs," in
Proc. of the 40th IEEE National Aerospace and Electronics Conference, vol. 2, pp.
732-738, Piscataway, 1988.
[3] E. V. Berard, Essays on Object-Oriented Software Engineering, Vol.I, Prentice-Hall,
1993.
[4] B.W. Boehm , J.R. Brown and M. Lipow , \Quantitative Evaluation of Software
Quality," in IEEE 2nd International Conference on Software Engineering, pp. 286-
299, 1976.
[5] G. Booch, Object-Oriented Analysis and Design with Applications (2nd edition), Ben-
jamin Cummings, 1994.
[6] T.A. Budd, An Introduction to Object-Oriented Programming, Addison-Wesley, 1991.
30
[7] L. Cardelli, \A Semantics of Multiple Inheritance," in Journal of Information and
Computation, vol. 76, pp. 138-164, 1988.
[8] L. Cardelli et al., \Modula-3 Language Denition," in ACM SIGPLAN Notices, vol.
27, pp. 15-42, August 1992.
[9] S.R. Chidamber and C.F. Kemerer, \Towards a Metric Suite for Object-Oriented
Design," in Object-Oriented Programming Systems Languages and Applications
(OOPSLA), Special Issue of SIGPLAN Notices, vol. 26, Oct. 1991.
[10] S.R. Chidamber and C.F. Kemerer, \A Metric Suite for Object-Oriented Design," in
IEEE Transactions on Software Engineering, vol. 20, pp. 476-493, June 1994.
[11] P. Coad and E. Yourdon, Object-Oriented Design, Prentice-Hall, 1991.
[12] C.J. Date, Relational Database: Selected Writings, Addison Wesley, 1986.
[13] M.A. Ellis and B. Stroustrup, The Annotated C++ Reference Manual, Addison-
Wesley, 1990.
[14] D.W. Embley and S.N. Woodeld, \Cohesion and Coupling for Abstract Data Ty-
pes," in 6th International Phoenix Conference on Computers and Communications,
pp. 292-234, IEEE Computer Society Press, Arizona, 1987.
[15] D.W. Embley and S.N. Woodeld, \Assessing the Quality of Abstract Data Types
Written in Ada," in International Conference on Software Engineering, pp. 144-153,
IEEE Computer Society Press, 1988.
[16] G. Engels and G. Kappel, \Object-Oriented Systems Development: Will the New Ap-
proach Solve Old Problems?," in Proceedings of the IFIP94 World Congress, Vol.III,
ed. K. Duncan and K. Krueger, North-Holland, 1994.
[17] A. Goldberg, Smalltalk-80: The Interactive Programming Environment, Addison
Wesley, 1984.
[18] B. Henderson-Sellers, S.C. Bilow and W. Harrison, \Workshop Report on Pragmatic
and Theoretical Directions in Object-Oriented Software Metrics at OOPSLA'94," in
OOPS Messenger, vol. 5, pp. 78-80, October 1994.
[19] M. Hitz and B. Montazeri, \Measuring Product Attributes of Object-Oriented Sy-
stems," in European Software Engineering Conference (ESEC'95), Sept. 1995 (to
appear).
[20] S. Hong, \A Class Normalization Approach to the Design of Object-Oriented Da-
tabases," in Proc TOOLS USA '91 (Technology of Object-Oriented Languages and
Systems), pp. 63-71, 1991.
[21] Hood Working Group, The HOOD (Hierarchical Object-Oriented Design) User Ma-
nual, Issue 3.0, European Space Agency, Sept. 1989.
31
[22] C. Jean and A. Strohmeier, \An Experience in Teaching OOD for Ada Software," in
ACM SIGSOFT Software Engineering Notes, vol. 15, pp. 44-49, Oct. 1990.
[23] R.E. Johnson and B. Foote, \Designing reusable classes," in Journal of Object-
Oriented Programming (JOOP), vol. 1, pp. 22-35, 1988.
[24] R. Jungclaus, G. Saake, T. Hartmann and C. Sernadas, \TROLL - A Language
for Object-Oriented Specication of Information Systems," ACM Transactions on
Information Systems (to appear), 1995.
[25] G. Kappel and M. Schre
, \Object/Behavior Diagrams," in Proceedings of the 7th
International Conference on Data Engineering, pp. 530-539, IEEE Computer Society
Press, Kobe, Japan, April 1991.
[26] G. Kappel, J. Overbeck and M. Schre
, \A Process Model for Object-Oriented
Development," Technical Report MOOD 92/08, presented at Workshop on Object-
Oriented Software Development Process at ECOOP'92, Utrecht, July 1992.
[27] S. Keene, Object-Oriented Programming In Common Lisp: A Programmers Guide
To Common Lisp Object System, Addison-Wesley, 1988.
[28] T. Korson and J.D. McGregor, \Understanding Object-Oriented: A Unifying Para-
digm," in Communications of the ACM, vol. 33, pp. 40-60, 1990.
[29] O. Lehrmann-Madsen, B. Mller-Pedersen and K. Nygaard, Object-Oriented Pro-
gramming in the BETA Programming Language, Addison Wesley, 1993.
[30] K.J. Lieberherr, I. Holland and A.J. Riel, \Object-Oriented Programming: An Ob-
jective Sense of Style," in Object-Oriented Programming Systems Languages and Ap-
plications (OOPSLA), Special Issue of SIGPLAN Notices, ed. N. Meyrowitz, vol. 23,
pp. 323-343, Nov. 1988.
[31] K.J. Lieberherr and I. Holland, \Assuring good style for object-oriented program-
ming," in IEEE Software, pp. 38-48, Sept. 1989.
[32] K.J. Lieberherr and C. Xiao, \Formal Foundations for Object-Oriented Data Mode-
ling," in IEEE Transactions on Knowledge and Data Engineering, vol. 5, pp. 462-478,
June 1993.
[33] K.J. Lieberherr, I. Silva-Lepe and C. Xiao, \Adaptive Object-Oriented Programming
using Graph-Based Customization," in Communications of the ACM (CACM), vol.
37, pp. 94-101, May 1994.
[34] B. Liskov and J.M. Wing, \A New Denition of the Subtype Relation," in Proc of the
7th European Conference on Object-Oriented Programming (ECOOP'93), ed. O.M.
Nierstrasz, pp. 118-141, Springer LNCS 707, Kaiserslautern, 1993.
[35] V.M. Markowitz and A. Shoshani, \On the Correctness of Representing Extended
ER Structures in the Relational Model," in Proceedings of the ACM-SIGMOD Int.
Conf. on the Management of Data, pp. 430-439, Portland, 1989.
32
[36] D. Merkl, A M. Tjoa and G. Kappel, \Structuring a Library of Reusable Software
Components Using An Articial Neural Network," in Proc of the 2nd International
Conference on Achieving Quality in Software (AQuIS'93), Venice, Oct. 1993.
[37] B. Meyer, Object-Oriented Software Construction, Prentice-Hall, 1988.
[38] B. Meyer, \Tools for the New Culture: Lessons from the Design of the Eiel Class
Library," in Communications of the ACM, vol. 33, pp. 68-88, 1990.
[39] B. Meyer, Eiel: The Language, Prentice-Hall, 1992.
[40] R.T. Mittermeir, \Design Aspects Supporting Software Reuse," in Software Reuse,
ed. L. Dusink and P. Hall, pp. 115-119, Springer, 1989.
[41] D.R. Moreau and W.D. Dominick, \Object-Oriented Graphical Information Systems:
Research Plan and Evaluation Metrics," in The Journal of Systems and Software, vol.
10, pp. 23-28, 1989.
[42] D.R. Moreau and W.D. Dominick, \A Programming Environment Evaluation Me-
thodology for Object-Oriented Systems: Part I - The Methodology," in Journal of
Object-Oriented Programming (JOOP), pp. 38-52, May/June 1990.
[43] D.R. Moreau and W.D. Dominick, \A Programming Environment Evaluation Metho-
dology for Object-Oriented Systems: Part II - Test Case Applications," in Journal
of Object-Oriented Programming (JOOP), pp. 23-32, September/Oct. 1990.
[44] G.J. Myers, Composite/Structured Design, Van Nostrand Reinhold, 1978.
[45] K.W. Nielsen, \Task coupling and cohesion in Ada," in Ada Letters, vol. 6, pp. 44-52,
July/August 1986.
[46] O.M. Nierstrasz, \A Survey of Object-Oriented Concepts," in Object-Oriented Con-
cepts, Databases and Applications, ed. W. Kim and F. Lochovsky, pp. 3-21, ACM
Press and Addison-Wesley, 1989.
[47] O. Nierstrasz, S. Gibbs and D. Tsichritzis, \Component-Oriented Software Develop-
ment," in Communications of the ACM , vol. 35, pp. 160-165, 1992.
[48] M. Page-Jones, The Practical Guide to Structured Systems Development, Yourdon
Press, 1980.
[49] M. Page-Jones, \Comparing Techniques by Means of Encapsulation and Con-
nascence," in Communications of the ACM, vol. 35, pp. 147-151, Sept. 1992.
[50] D. Rocacher, \Smalltalk-80 and Smack: towards a methodological approach to soft-
ware quality," in Proc. Esprit'88 Putting the Technology to Use, pp. 492-507, North
Holland, 1988.
[51] C. Schaert et al., \An Introduction to Trellis/Owl," in Object-Oriented Program-
ming Systems Languages and Applications (OOPSLA), Special Issue of SIGPLAN
Notices, ed. N. Meyrowitz , vol. 21, pp. 9-16, Dec. 1986.
33
[52] A. Snyder, \Inheritance and the Development of Encapsulated Software Compo-
nents," in Research Directions in Object-Oriented Programming, ed. B. Shriver and
P. Wegner, pp. 165-188, The MIT Press, 1987.
[53] W. Stevens, G. Myers and L. Constantine, \Structured Design," in IBM Systems
Journal, vol. 13, pp. 115-139, 1974.
[54] J. Stiebellehner, G. Kappel and H. Schauer, \Kopplungs- und Konzentrationszahlen
fur objektorientierte Software," in Bericht des GI-Workshops "Software-Metriken",
Magdeburg (BRD), Sept. 1994.
[55] D.P. Tegarden, S.D. Sheetz and D.E. Monarchi, \A Software Complexity Model of
Object-Oriented Systems," in Journal of Decision Support Systems, 1994.
[56] P. Wegner, \Dimensions of Object-Based Language Design," in Object-Oriented Pro-
gramming Systems Languages and Applications (OOPSLA), Special Issue of SIG-
PLAN Notices, vol. 22, pp. 168-182, Dez. 1987.
[57] A. Wirfs-Brock and B. Wilkerson, \Variables Limit Reusability," in Journal of
Object-Oriented Programming (JOOP), pp. 34-40, May/June 1989.
[58] R. Wirfs-Brock, B. Wilkerson and L. Wiener, Designing Object-Oriented Software,
Prentice Hall, 1990.
[59] E. Yourdon and L.L. Constantine, Structured Design, Prentice-Hall, 1979.
34