What is Object-Oriented Design (OOD)?
Here are some ways that various authors have
described Object-Oriented Design:
-
The goal of object-oriented design is to create an
architecture for implementation. Designs are represented
in terms of objects and classes and the relationships
among them. [Xiaoping Jia]
-
OOD is the process of constructing a solution's
object model. Said another way, OOD is the process
of breaking down a solution into a number of constituent
objects. [Anthony Sintes]
-
Object-oriented design centers on finding an appropriate
set of classes and defining their contents and behavior.
It involves determining the proper use set of classes and
then filling in the details of their implementation.
Object-oriented design is fundamentally a three-step
process: identifying the classes, characterizing them,
and then defining the associated actions. [Stephen P. Reiss]
Key Concerns of an Object-Oriented Design
Here are some key concerns that a developer
must have when preparing an object-oriented design:
-
Does the design satisfy all the requirements
and constraints, and provide all required services?
-
Is the design flexible enough to permit future
changes and enhancements easily?
-
Is the design feasible for actual implementation,
and, if so, can it be implemented efficiently?
-
Will the implementation of the design be deployable
on the required platform with relative ease?
Principle of Modularity
A complex software system should
consist of a set of modules that
are highly cohesive, but
loosely coupled.
-
Cohesion refers to the extent to
which the entities within a module are closely
related.
-
Coupling refers to the extent to
which the modules themselves are interdependent.
When you actually begin to think seriously
about the classes you are going to need for
a software development project, you need to
keep this Principle in mind.
A good rule of thumb to remember is that
a good design should attempt to
maximize cohesion and
minimize coupling.
You should think of this Principle as applying
at all levels and stages of development, whether
at the highest level of class relationships or
the lowest level of method implementation.
Static Structure and the Domain Model
Use cases can help us to capture the system
vocabulary for a problem we are trying
to solve. This system vocabulary will contain
the terms which characterize the problem
domain, and will help us build a domain
model, i.e., a list of all objects we need
to model in order to properly model the complete
system. When we understand how these objects relate
to one another we shall have some kind of sense of
the static structure of the system. We
need to have this before we can begin to ask how
the system behaves dynamically, i.e., how the various
objects interact at run-time.
Here are some high level descriptions of some of
the key activities we need to perform when applying
OOD:
-
Generate an initial list of objects.
-
Refine the responsibilities of each object.
-
Detail the relationships between objects.
-
Determine/develop the points of interaction (the places
where one object uses another).
-
Build the model.
Note that CRC cards can be a big help with the first three
of the activities in the above list.
As we think more and more about the model, we may find that
a design language like the UML (Unified Modeling Language)
will be helpful in describing the various parts of the model
and their interactions to others, as well as to ourselves.
We must also be continually on the lookout for situations
in which we might be able to make use of a design
pattern, i.e., a previously-existing solution to
a problem that has already been solved. Recognizing and
using design patterns is one way of tring to avoid
having to "re-invent the wheel".
Possible Relationships between Classes
It is a good idea to construct a UML class diagram to
show the class relationships in any software development
project you are working on. The most frequently encountered
relationships are discussed below. It may be worth noting
that some authors seem to suggest that the only relationships
that are really clear-cut, useful, and occur frequently, are
inheritance and composition, and that composition is to be
favored over inheritance if there's a choice. Those authors
also suggest that the problems with the other relationships
stem from the fact that it's often very difficult to know exactly
what a particular developer means by his/her interpretation
of that relationship.
-
inheritance, generalization, specialization
-
The terms generalization and specialization
are both used to refer to inheritance, which in turn
refers to the "is-a" relationship. A better conceptual model
may be to think of a "may be substituted for" relationship, or
an "is-a-kind-of" relationship, rather than a strict "is-a"
relationship.
Example:
A Student is-a-kind-of Person. Or, a Person may be
considered a generalization of a Student. That is, a Student
may be considered a specialization of a Person. Or, a Student
"may be substituted for" a Person because a Student is-a-kind-of
Person.
-
association
-
The term association refers to a relationship
that is a little "deeper" than than dependency (see below),
in that it's a structural relationship in which one object
is "connected" to another object. This usually means that
an object of one class will contain a reference to an
object of another class as one of its member variables.
Example:
A Person borrows-from a Bank.
-
The term composition is a special kind
of association which models the "has-a" relationship.
In this case the relationship is a whole/part one in
which the whole and its parts "come and go as one".
Example:
A Car has-a SteeringWheel.
But, if a Car object goes to the junk yard, so (probably)
does its SteeringWheel object.
-
The term aggregation is a special kind of
association, which also models the "has-a" (or "is-a-part-of"
or "whole/part") which is less "rigorous" that composition,
in that in this case the relationship is among "peers" (i.e.,
among equally "important" entities which exist independently
of each other).
Example:
A Bank has-a Customer. But, if
a Customer object dies, the Bank carries on with its other
Customer objects. Similarly, if a customer's Bank object
closes down, the customer carries on and simply finds
another Bank object with which to do business.
-
dependency
-
The term dependency, refers to the
relationship in which one object depends on
another object's specification. This typically
occurs when an object of one class "uses" an
object of another class, and a change in the
specification of the class being used will
typically require an update to the dependent
object's class.
Examples:
-
A Purse class may depend on (i.e.,
"use") a Coin class in order to
compute the total amount of money contained
in a Purse object. If the interface
to the Coin class is changed in some
way, then one or more methods in the Purse
class interface that take a Coin object
as a parameter and perhaps call one or more of
its methods may have to be changed as well.
-
If a Psychiatrist object's
examine(...) method takes a
Patient object as an argument
and calls the Patient object's
queryMood() method, then if the name
or argument list of the queryMood()
method changes you will have to update
how the Psychiatrist object calls
this method.
CRC Cards (for discovering classes, responsibilities and collaborators)
CRC cards were first introduced by Kent Beck and Ward Cunningham
in 1989 at a conference on "Object-Oriented Systems, Languages
and Applications".
-
CRC = Class Name, Responsibilities and Collaborators
-
A CRC card is simply a 3 by 5 card on which these
are written (generally as the result of team or group efforts
of some kind that are as interactive as possible; producing
them is not a solitary effort)
-
Responsibilities help define the purpose of a class
-
Collaborations help determine how it interacts with other classes
-
Among the many advantages of CRC cards are these: They are
cheap, widely available,
and easily modifiable. They also encourage experimentation
and permit role-playing. Finally, the physical separation
of the cards suggests separation of software components,
and the size of a card limits the size of component code.
-
When should CRC cards be used?
-
During the initial stages of design
-
On smaller projects
-
To flesh out responsibilities and collaborations
-
To walk through a "scenario": in addition to finding
the responsibilities and collaborators, you may find
you understand the scenario better
Question:
How might you use CRC cards to help in your development of
a program to play the game of Mastermind?
List of All Topics