Topic 16: Object-oriented Design II
Synopsis
- Find the objects
- Find the classes¤
- Specify the relationships
- Design the interactions
- Refine the design
Class¤ roles (highest level)
- Client (consumer)
- Server (resource)
- Agent (intermediary)
Class¤ roles (lower level)
- Abstraction¤ (root class¤)
- Concept (node class¤)
- Datum (problem space)
- Data Type (solution space)
- Container
- Property (mixin¤)
- Process abstraction¤
- Wrapper (interface¤ adjustment)
- Handle (indirection - OO equivalent of pointer)
- Inheritance vs aggregation¤
("is a" vs "has a")
- Common interface¤ vs common implementation¤
("is a" vs "is implemented as a")
- Concepts vs instances¤
("is a" vs "is an example of")
- Ownership vs clientship
("possesses" vs "uses")
- Public inheritance¤ (abstraction¤, shared interface¤)
- Private inheritance¤ (1-to-1 implementation¤)
- Having a member¤ (many-to-1 implementation¤)
- Accessing another object (many-to-many implementation¤)
- Being an instance¤ (relationship between conceptual and concrete)
- Is this class¤ a more general/specific version of
that one? Do they share a common interface¤?
- Is this class¤ implemented in terms of that one?
- Is this class¤ implemented in terms of those ones?
- Does this class¤ make use of another (without actually
owning an instance¤ of it)?
- The overall behaviour¤ of an OO system emerges from the
interactions between its components
- Individual behaviours¤ may be achieved by one object
calling another...
- ...or by two or more objects supplying services under
the control of a coordinating object or function (a
"mechanism")
- Such behaviours¤ and mechanisms fall into well-known patterns
- Source/sink
(e.g. cin/cout)
- Processing
(e.g. iterating a list, walking a tree)
- Transformation
(e.g. applying some sequence of operations to a datum)
- Filtering
(e.g. selecting a subset of objects based on some criterion)
- Response
(e.g. reacting to some stimulus, often polymorphically)
- Many other (more complex) patterns
(see also "Topic 18: Design Patterns")
- Dependency diagrams, showing classes¤ and connectors
indicating method calls between them
- Timelines indicating the method calling
sequence and the flow of information between objects
- See "Topic
17: The UML Notation"
- Once the preliminary design is complete, go back and
look for...
- ...tightly coupled classes¤
(may indicate a common abstraction¤ or even a single class¤)
- ...large or "fuzzy" classes¤ with diverse behaviours¤ and complex
interfaces¤
(may indicate a need to split the class¤)
- ...unrelated, but structurally or functionally similar classes¤
(may indicate a need to abstract a common parent, or
merge the two hierarchies)
- ...repeated code in methods of distinct classes¤
(may be able to abstract to a parent class¤¤ or a mixin¤)
- May need to iterate earlier design phases
- May have to add new concepts drawn from problem domain
- May have to junk the entire design and start again!
- Discover the key abstractions¤ (candidate classes¤)
in the domain
- Identify the semantics of classes¤ and objects
(purpose -> function -> interface¤)
- Identify relationships between classes¤/objects
("is a", "is implemented as", "has a", "instantiates a")
- Documenting the behaviour¤ and interface¤ results
in a "contract" (and reduces coupling)
- Identify the interactions between objects (who calls whom,
who provides services for whom)
- Once the design is done, look for missed opportunities
(to factor out commonality, to merge hierarchies, etc.)
- Know what you're trying to achieve
(Have specific, tangible, realizable, measurable goals)
- Design for the long view
- Use existing models
- Reward re-use (choose your metric carefully)
- Use classes¤ to represent concepts
("If it's a separate idea, make it a class¤")
- Use objects to represent things
("If it's a separate entity, make it an object")
- Miminize your interface¤
- Miminize class¤ dependencies
- Abstract commonality into base classes¤¤ and/or templates
- Don't use global variables or functions
- Don't use public data members¤¤
- Don't use data members¤¤ to store "type" information
(use virtual functions¤ instead)
- Use the language of the problem domain
- Optimize later
- Low degree of coupling
(fewer interclass¤ function calls)
- High degree of cohesion
(classes¤ do most of their work "internally")
- Minimalism and sufficiency
(no more or fewer than the necessary interfaces¤ and behaviours¤)
- Reuse
(of previously-designed and/or standard components)
- Reflects the problem domain
(classes¤ correspond to concepts and abstractions¤ in the
problem space, objects correspond to things in the
problem space)
- Solves the problem!
- Pressman: Chapter 21
- Sommerville: Chapter 14
- Stroustrup: Chapters 23 to 25
- Schach: Chapters 12 and 13
This material is part of the CSE2305 - Object-Oriented
Software Engineering course.
Copyright © Jon McCormack & Damian Conway, 1998–2005. All rights
reserved.