| CS 535: Object-Oriented Programming & Design |
|
---|
Fall Semester, 1997
Doc 26, Some Heuristics
To Lecture Notes Index
San Diego State University -- This page last updated 03-Dec-97
Contents of Doc 26, Some Heuristics
- Meyer's Criteria for Evaluating for Modularity
- Basic Heuristics
- Relationships between Objects
- Heuristics for the Uses Relationship
- Containment Relationship
- Semantic Constraints Between Classes
- More Containment Heuristics
References
Object-Oriented Design Heuristics, Riel, 1996
Various sections in chapters 2-4 as indicated by the listed heuristics
Decomposability
Composability
Understandability
Protection
Continuity
2.1 All data should be hidden within its class
2.8 A class should capture one and only one key abstraction
2.9 Keep related data and behavior in one place
3.1 Distribute system intelligence horizontally as uniformly as possible
3.2 Do not create god classes in your system
3.3 Beware of classes that have many accessor (get-set) methods defined in
their public interface. Having many implies that the related data and behavior
are not being kept in one place
3.4 Beware of classes with too much noncommunicating behavior
2.11 Be sure the abstractions that you model are classes and not simply the
roles objects play
3.9 Do not turn an operation into a class
Type of Relations:
- Uses
- (Object)
- Containment
- (Object)
- Inheritance
- (Class)
- Association
- (Object)
Uses
- Object A uses object B if A sends a message to B
-
- Usually assume that A and B objects of different classes
-
- A is the sender, B is the receiver
Containment
- Class A contains class B when A has a field of type B
- That is an object of type A will have an object of type B inside
it
Six different Ways to implement Uses
How does the sender access the receiver ?
1. Containment
- The receiver is a field in the sender
class Sender
{
Receiver here;
public void method()
{
here.sendAMessage();
}
}
2. Argument of a method
- The receiver is an argument in one of the senders methods
class Sender
{
public void method(Receiver here)
{
here.sendAMessage();
}
}
3. Ask someone else
- The sender asks someone else to give them the receiver
-
- How does receiver access the someone else?
class Sender
{
public void method()
{
Receiver here = someoneElse.getReceiver();
here.sendAMessage();
}
}
4. Global
- The receiver is global to the sender
5. Creation
- The receiver is created by the sender
class Sender
{
public void method()
{
Receiver here = new Receiver();
here.sendAMessage();
}
}
6 Referential Attribute (Other)
4.1 Minimize the number of classes with another class collaborates
4.5 If class A contains objects of class B, then A should be sending messages
to it's fields of type B.
The one exception to 4.5 are container classes
4.5 prohibits the following behavior in a non-container class
class Foo
{
Bar data;
public Bar getData()
{
return data;
}
public void setData( Bar newData)
{
data = newData;
}
}
4.6 Most of the methods defined on a class should be using most of the fields
in the class most of the time
4.7 Classes should not contain more objects than a developer can fit in his or
her short-term memory. A common value for this number is 6
Narrow and Deep Containment Hierarchies
Combining fields into new classes can reduce the number of fields in a class
A broad and shallow Containment Hierarchy
A narrow and deep Containment Hierarchy
4.8 Distribute system intelligence vertically down narrow and deep containment
hierarchies.
Examples of semantic constraint:
- A meal should start with appetizer, then the entree, then dessert
- A meal will have two vegetables out of a choice of peas, corn, squash, and
asparagus, but peas and corn are not allowed in the same meal
4.9 When implementing semantic constraints, it is best to implement them in
terms of the class definition. Often this will lead to a proliferation of
classes, in which case the constraint must be implemented in the behavior of
the class - usually, but not necessarily, in the constructor.
4.10 When implementing semantic constraints in the constructor of a class,
place the constraint test in the constructor as far down a containment
hierarchy as a the domain allows.
4.11 The semantic information on which a constraint is based is best placed in
a central, third-party object when that information is volatile.
4.12 The semantic information on which a constraint is based is best
decentralized among the classes involved in the constraint when that
information is stable.
4.14 Objects that are contained in the same containing class should not have a
uses relationships between them.
Contained Objects with uses relationships
The containing class should send messages to the contained objects
4.13 A class must know what it contains, but it should not know who contains
it.
If a number of classes depend on each other in a complex way, you can violate
4.13 to reduce the number of classes they interact with.
Wrap the classes in a containing class.
Each contained class sends a message to the containing class, which broadcasts
the message to the proper contained objects
Complex interactions
Replacing complex interaction with containing class