Introduction to Object Oriented Analysis and Design
Stephen A. Sawyer
Introduction
One of the great aspects of OOP is that you can study OOP methodologies and concepts
without ever having access to an OOP language. Most books on these topics are not
language-specific. So its possible to tackle some of the issues you will be facing in your
own eventual OOP work long before you write your first line of OOP code.
As I first started learning how to program in an OO style, my first reaction was Hey! This
is easy!, which it is. The syntax of OOP, and the big three concepts of Polymorphism,
Encapsulation and Inheritance, are very easy to grasp, and just as easy (well, almost as
easy ) to actually get working. For example, in Visual FoxPro, we have about a halfdozen new commands and functions, and one new operator, and thats it. A child can do it.
However, as is the case with many simple, yet elegant, concepts, after a while you begin to
appreciate the subtlety involved in actually designing and implementing a set of object
classes. You have many choices to make in designing a set of software objects, and
because of inheritance, you live with your decisions in a way that were unfamiliar with,
coming from a procedural programming background, or even a procedural/object based
background.
So what exactly is Object Oriented Analysis and Design?
Object oriented analysis and design is a methodology for arriving at a specific set of
objects necessary to complete a software system. As the term suggests, there are two parts
of this process. Analysis, and Design. Whats the difference?
Analysis is implementation independent. Analysis makes certain assumptions, and ignores
certain realities. First, analysis assumes that were working with a perfect development
tool, and as a result, is not concerned at all with how the software will eventually be
implemented (or even if the implementation is possible!). It is entirely user-centric. It
answers the what question, rather than the how.
By contrast, Design is involved with implementation, and is intimately concerned with the
actual development tool selected for the project. It answers the how question after
analysis has decided what.
In procedural programming, the first step in developing a piece of software is to create a
written specification of the project. This is also the point of departure for developing an
object-oriented system. In procedural programming the conventional wisdom has long
been to write a flow chart as part of the design phase of each project. Creating such a
flowchart serves several purposes.
Introduction to Object Oriented Analysis and Design - Page 1
The flowchart helps the programmer to see the big picture, to clearly define the
purpose of the system, what functions are to be performed, and to be able to
clearly communicate this understanding back to the end users.
To refine the purpose and interaction between each procedure or function
To clearly think through the logic to be used to perform the tasks required by the
system and its individual procedures.
Object oriented analysis and design can yield a document that serves a similar purpose as
the procedural programmers flowchart, but also serves needs unique to an OO system.
It allows the developer, or development team, to:
verify their understanding of the purpose and operation of the system with the users
to identify all of the components (objects) of the system
to define the relationships, interactions, dependencies, and responsibilities of each
object in the system
Is OOA&D that much different than flow-charting?
The short answer is yes. Object-oriented systems differ from a procedural system in
three important ways which makes OOA&D a necessity, even on a small system, whereas
flowcharting was considered by many to be an option. These three differences relate to the
three determining properties of all object-oriented programming languages, Encapsulation,
Polymorphism, and Inheritance.
Procedural systems deal with a data/code dichotomy. The data, usually stored in a
database, is manipulated by the code. As a result, there is no difficulty in deciding where to
place responsibility for a particular function. There is no who does what? kind of
question to ask, and it is not unusual for several functions or procedures that do almost
identical tasks to be scattered throughout an application, especially one which has been in
maintenance for several years. Object-oriented systems, on the other hand, make use of
the concept of encapsulation - each object possesses both code (methods) and data
(properties), so we are continually faced with a decision about which object has
responsibility to perform which functions, and which object holds which data. Another
issue related to encapsulation is Which of these properties and methods should be visible
to other objects?
The second major difference between OO and procedural systems is that an object
template, or class can be subclassed, so that a group of object classes (and the objects
based on those classes) all inherit properties and methods from a single superclass. Thus
we not only need to be aware of the interaction between objects in a flat-two-dimensional
sense, but in a three-dimensional sense that includes the class hierarchies of which our
object classes are members.
Introduction to Object Oriented Analysis and Design - Page 2
With the exception of a few special, and very limited cases, procedural languages cannot
implement polymorphism, because the name of a procedure is all that is used to identify
that procedure. The procedure is not associated with any object other than the application
itself. Thus, two procedures, even though they may perform an identical function, but
acting on different data sets, must have a different name, giving rise to procedure names
such as PrintInvoice() and PrintPO(). In an OO system, on the other hand, each procedure
(called methods in OOP) is associated with a single object. As a result if we have one
object that represents an invoice, and another object that represents a purchase order,
either item can be printed by calling the appropriate objects Print() method.
If this Print() method is going to be invoked by numerous other objects in the system, it
must present a uniform interface or signature to the rest of the system, i.e. each Print()
method must accept the same number of arguments, arguments of the same data types,
and return the same type of value as all the other Print() methods in the system.
Thus the things that make Object-Oriented Programming what it is, Encapsulation,
Polymorphism and Inheritance, also create a potential nightmare if the objects we create
and use are not carefully thought out in advance. This gives rise to the clich Ive heard
time and again - that 70% of the effort in developing OOP applications is devoted to
analysis and design, and 30% to implementation, testing and maintenance.
When actually creating object classes, the reason for this increased emphasis on analysis
and design becomes obvious. Which object is responsible for this function? Where in our
inheritance hierarchy do we introduce this method? Do we design this object to modify its
own behavior or change its state, or do we rely on another object to act on this one? How
and where do we store a reference to this object so other objects can communicate with
it? Does an object register itself with other objects, or do we maintain a central
repository of object references? Should this object be instantiated as a property of another
object, contained by another object, or should it be instantiated as a global variable? Above
all, how do we achieve maximum flexibility, object re-use, and ease future maintenance?
While there are no hard and fast rules for making these kinds of decisions, there are certain
ways of approaching the problem that can tackle it in an organized and logical manner.
These methods are what the art of Object-Oriented Analysis and Design are all about.
How OOA&D affects the software life-cycle
Before discussing these techniques, lets look at how the software life-cycle differs between
object-oriented and procedural programming.
For many years, the most prevalent model for discussing the life cycle of a software
project has been the Waterfall Model. Figure 1 is a graphical representation of this
model.
Introduction to Object Oriented Analysis and Design - Page 3
System
Specification
Requirements
Analysis
Architectural
Design
Detailed
Design
Coding And
Debugging
Unit
Testing
System
Testing
Maintenance
Figure 1 - The Software Life Cycle Waterfall Model
Note that this illustration shows that the process proceeds from the top left to the bottom
right. Although in an acknowledgment of real-world software development, this particular
illustration (McConnel, 1993) shows that sometimes a previous step must be re-visited
when a subsequent step shows that something is missing in the previous step. For instance,
it may become evident during architectural design that there is a requirement that was
overlooked during requirements analysis. In traditional software development using
procedural development tools, this was usually seen as a failure in the process, and
begrudgingly accepted as an unavoidable consequence of human frailty.
Traditional software life-cycle models depict a clear division between the analysis and
design of a system. The analysis people would do their job, then toss the specs over the
partition to the design team to continue with design and implementation.
By contrast, development of object-oriented software is not ever viewed as a linear,
beginning-to-end process, but rather as an iterative process, in which each step in the
process may, and indeed, is expected to cause the developer(s) to re-visit previous steps in
the process. And, while it is convenient to view analysis and design of object-oriented
systems as separate parts of the process, the division is much less clear-cut.
The following illustration gives a much more accurate idea of the iterative process in
developing an object-oriented system. For purposes of clarity, the process illustrated has
been pared to the functions of System Specification (Analysis), Design, Coding and
Debugging (Implementation) and Testing:
Introduction to Object Oriented Analysis and Design - Page 4
Coding And
Debugging
(Implementation)
Design
System
Specification
(Analysis)
System
Testing
Figure 2 - The Gordian Knot cycle of OO application development
Here we see that like the traditional waterfall methodology, the process may start with
analysis, and end with testing (and maintenance), but any step in the process can (and
again, is expected to) lead back to an earlier step.
It should be noted that a shortcoming of both of these diagrams, is that there is nothing
that signifies the relative emphasis, or the amount of time and effort spent on each phase
of the operation.
The following diagram addresses this issue, and compares the amount of effort devoted to
analysis and design in object-oriented systems, with that of a procedural system.
Introduction to Object Oriented Analysis and Design - Page 5
Procedural
System
Object-Oriented
System
Figure 3 - Comparison of procedural and OO software life cycles
This illustration, in addition to implying the iterative nature of object-oriented software
development, also shows the relatively greater importance that analysis and design assume
in relation to implementation.
Object Oriented Analysis and Design
The following discussion will describe various activities as steps in Object Oriented
Analysis and Design. This indicates only that the later steps require that prior steps come
before. However, as already pointed out, OOA & D is an iterative process, so that going
back to step 3 while in step 4 is to be expected. The reason for this, is that each step
represents a refinement of the model developed up to that point, and during this
refinement, inadequacies of the model become apparent.
There are many different notational systems that have been devised to communicate
object-oriented designs. Most authors who have contributed to this discipline have
developed their own scheme or adapted others schemes for their use. To avoid getting
bogged down in the details of these notational schemes, this article will use non-standard
diagrams, or simple notational schemes to communicate the relevant ideas.
I would like to point out that in my study of this subject, that while many (if not most)
authors make a distinction between the methods applicable to analysis and those
applicable to design, my feeling is that the only difference in many cases is whether we are
examining an analysis object, that is, a candidate object that is being considered from the
Introduction to Object Oriented Analysis and Design - Page 6
application/user perspective, or one that is being considered from a
language/implementation perspective.
Because of this, I will be discussing the techniques without reference to whether it is used
in analysis or design, because in my opinion most can be used in both phases.
Object Discovery
The first step in analysis is to examine the functional specification and to identify as
many of the objects in the system being modeled as possible. In design, it is to examine the
list of objects discovered during analysis, and begin identifying the implementation-specific
objects necessary to accommodate the requirements used to begin the analysis. In both
cases, this will yield a list of objects, which might include items such as Customer, Invoice,
Employee, Product, Discount, Job etc.
In analysis, this is a very high-level activity, and will usually involve the active participation
of the client/user. Being a high-level activity, no thought is given to implementation at this
point. The purpose is solely to model, using object terminology, the real-world system that
the system is to model. In design of a multi-person project, interaction with those involved
in the analysis (and probable refinement of that analysis) will be the norm.
There are various cues to identifying objects in a functional specification, in consultation
with the client/users, and in examining the analysis document.
Using a data perspective, look for nouns in the functional specification or analysis
document.
Using a functional perspective, look for verbs as potential object identifiers. If some
act is performed, some object must be the actor.
Using a behavioral perspective, look for communications, which can identify senders
and receivers as potential objects. Look also for events that the system must respond
to. Potential objects are entities that are responsible for making a response to such
events.
After initial object discovery is completed, the process boils down to a series of
questions that are asked about each object discovered, or about collections or subsets of
all of the objects in the system under development. This process refines the developers
understanding of the role each object should play, and in most cases, will result in the
addition of new objects, and the elimination of others.
The first step is to examine the list of objects, and to begin organizing them into two
hierarchies
Establishment of class hierarchies - Does the object share certain core attributes
and/or behaviors with other objects?
Introduction to Object Oriented Analysis and Design - Page 7
The first hierarchy relates to the principle of inheritance. This hierarchy is sometimes
referred to as a generalization-specialization hierarchy, or gen-spec hierarchy. This
terminology is particularly appropriate, as it leads to a mind-set that aids in later design
activities which will be discussed later.
Organizing object classes into a gen-spec hierarchy helps to identify which objects share
certain behaviors and attributes, and which may be subclassed (and therefore can inherit
their members) from a common ancestor. Note that such an ancestor class can be a
concrete class, that will be instantiated as an object, or it can be what is referred to as an
abstract class, i.e. a class that is never instantiated, but exists exclusively to provide a
common pool of behaviors and attributes that can be specialized in its subclasses.
Gen-spec hierarchies can also be described as is-a hierarchies; each subclass represents a
specialization of the superclass, and is-a special case of the superclass.
The following diagram illustrates such a hierarchy. During analysis of a particular system,
objects that represent Sales Person, Supervisor and Customer may have been identified.
When establishing object class hierarchies, it is realized that these three objects have
certain attributes and behaviors in common, and can be subclassed from an abstract class,
Person. This class is considered to be abstract in this system, because there will be no
objects instantiated from this class - each class that is-a person in the system, will always
be instantiated from one of the subclasses, Customer, Supervisor or Sales Person.
Person
Sales Person
Customer
Supervisor
Figure 4 - A Gen-Spec Diagram
A clue to the possible gen-spec hierarchies is the existence of adjectives in the list of
candidate objects, although an adjective could also suggest an object/class attribute.
Introduction to Object Oriented Analysis and Design - Page 8
Establishment of Containership Hierarchies - Is the object a part of another object?
The second type of hierarchy that must be defined is sometimes referred to as a wholepart hierarchy. Other possible terms are containership hierarchy or has-a hierarchies.
This type of hierarchy describes composite objects and the objects component parts.
Cardinality (the numerical ratio between the whole and its parts) is a further refinement of
this hierarchy. For instance, if we define an Invoice class, and define it as being made up of
(in part) Line Item objects, it would be probable that we would define the Invoice Class as
being made up of 1 to n Line Item objects.
Invoice
Object
Invoice
Line Item
Object
Line Item
Object
1,n
1,1
Line Item
Object
Line Item
Object
Line Item
Figure 3 - Two illustrations of whole-part hierarchies
In Figure 6, the rightmost diagram is a Coad-Yourdon diagram indicating both the wholepart relationship between Invoice objects and Line Item objects, and the bi-directional
cardinality - Invoice objects have at least one line item, and line items are associated with
one, and only one, invoice
As you can see, this process again may expose objects that were not previously identified.
Establishment of Object Relationships - Are there limits on the number of instances
of this object? Are the limits related to the existence of other objects?
In addition to the cardinality of whole-part hierarchies, the existence and cardinality of
other object relationships is to be established. This is very similar to defining relationships
between relational database tables and can use the same notation: Unlike is-a and hasIntroduction to Object Oriented Analysis and Design - Page 9
a class hierarchies, which pertain primarily to object classes, object relationships only
exist between instances of object classes.
Class 1
Class 2
Figure 4 - "Crow's Feet" notation showing a 1 to 0,n relationship
Roughing In Properties and Methods - What attributes and behaviors should
these objects possess?
Personification is a technique which can assist at this stage. The programmer or analyst
imagines that they are the object or object class being examined, and asks:
Attribute/property questions:
What do I know - what must I remember from one moment to the next?
How can I be described - what attributes are unique to me as an individual object, and
therefore require that I have properties to store these attributes?
Does my state change from one moment to the next?
Behavior/method questions:
Am I responsible for changing my state?
Is there any action I should take in response to a change of state?
What services am I expected to provide to other objects? (i.e. what are my
responsibilities within the system? To whom must I act as a server?)
What services do I expect to be provided by other objects? What objects will view me
as a client?
Identify collaborations between objects - What functions of the application cannot
be completed by individual objects by themselves?
Is there information that one object needs that it can obtain from another object?
Is there information that another object needs, that this object can provide?
Criteria for evaluating analyses or designs
Introduction to Object Oriented Analysis and Design - Page 10
Does the object have some data that it must remember? If not, the object should be
discarded, and its responsibilities transferred to another object.
Does the object have more than one attribute? If not, this should be viewed as a
challenge to the suitability of this object class. The object in question could
possibly be represented as an attribute of another object.
Does the object collaborate with other objects? If not, then this class would have no
methods, cannot receive messages (act as a server), and cannot send messages (act
as a client), and has no reason for existence.
Do all instances of this object class make use of all of its properties? If not, then the
class should be subclassed, and the unused properties should be included at the
new level in the class hierarchy.
Do all instances of this object make use of all of its methods? Again, if not, it should be
subclassed.
Is the object independent of the hardware that the application will be run on, or the
language used to implement the application? If yes, then it is an analysis object, if
no, then it is an implementation (design) object.
Criteria for evaluating an Object-Oriented design (implementation objects)
Minimal Coupling - The whole idea of encapsulation is to maximize loose coupling.
Strive to create objects that can exist and operate without error in the absence of other
objects in the system, i.e. it is a black box. Minimize the quantity and complexity of
messages used in this objects collaborations with other objects. Minimize dependency on
other objects which the object cannot instantiate if needed, or an external system state
which the object cannot control.
Maximum Cohesion - To maximize internal cohesion, each method should have only one
function (its function can be described using only one verb and one object). All of the
properties and methods of the object are related, and subclasses never override or delete
properties and methods inherited from superclasses.
Hierarchy depth - More than 7 levels in a gen-spec or whole-part class hierarchy should be
seen as a challenge to the design.
Simplicity and clarity - The object class should be easily visualized. If it cant be drawn on
a cocktail napkin, its probably overly complex. Any of the following should cause alarm
bells to sound in your head, and the object class should be re-examined;
More than one or two properties per method
More than six or seven exposed (public) methods
The need to collaborate (communicate) with more than 7 other objects
Introduction to Object Oriented Analysis and Design - Page 11
More than three arguments/parameters for methods
Excessive IF-THEN-ELSE or CASE statements in methods (using procedural code to
make decisions that should have been made in the inheritance hierarchy). Look for no
more than one branching statement for every five lines of code.
In addition, the following features should also be warning signs to a poor design:
Methods with different names that do the same thing, or conversely, methods with
identical names, that perform different actions.
Methods that do nothing other than pass control to another method - the OO version
of spaghetti code.
In general, small is the watchword in an OO design. Few class hierarchies, with few
subclasses, few methods in each class, and no more than one page (two screens full on
your monitor) of code per method means that each method, class and class hierarchy is
easily grasped.
BIBLIOGRAPHY
Edward Yourdon, Object-Oriented Systems Design, Prentice-Hall, 1994
ISBN 0-13-636325-3
Rebecca Wirfs-Brock, Brian Wilkerson and Lauren Wiener, Designing Object-Oriented
Software, Prentice-Hall, 1990
ISBN 0-13-629825-7
Steve McConnel, Code Complete, Microsoft Press, 1993
ISBN 1-55615-484-4
Introduction to Object Oriented Analysis and Design - Page 12