Object design is primarily adding details to the requirements analysis and making implementation decisions. Object design serves as the basis for implementation in an object-oriented paradigm. During object design, developers define solution domain objects to bridge the gap between the analysis model and the hardware/software platform defined during system design. This includes precisely describing object and subsystem interfaces, selecting off-the-shelf components, restructuring the object model to attain design goals such as extensibility and understandability, and opti-mizing the object model for performance. An object model describes how a com-ponent or system works, down to programming language classes or some other level that can be coded. The result of the object design activity is a detailed object model annotated with constraints and precise description for each element (Bruegge and Dutiot2004). The following figure shows object design in the software lifecycle (Bruegge and Dutoit1999). ‘‘Object design should consist solely of expanding the requirements model to account for the complexities introduced in selecting a par-ticular implementation—e.g. multiple computational resources, added objects to manage other objects, added objects to manage external interfaces, continue from analysis to design’’ (Coad and Yourdon1990) (Fig8.1).
Eliens describes the distinction between object-oriented analysis and design primarily as emphasis—emphasis on modeling the reality of the problem domain versus emphasis on providing an architectural model of a system that lends itself to implementation (Eliens1995).During object design we close the gap between the application objects and the off-the-shelf components by identifying additional solution objects and refining existing objects. This is shown in Fig.8.2. Object design includes Reuse, Service Specification, Object Model Restructuring, and Object Model Optimization. Object design like system design is not algorithmic.
It’s the developers who restructure and optimize the object model to address design goals such as maintainability, extensibility, efficiency, response time or timely delivery. Analysis reduces the gap between the problem and the machine by identifying objects representing problem-specific concepts. System design reduces
R. Y. Lee, Software Engineering: A Hands-On Approach,
DOI: 10.2991/978-94-6239-006-5_8, Atlantis Press and the author 2013
147
the gap between the problem and machine through a virtual machine, using reusable class and libraries. After several iterations of analysis and system design, the developers are usually left with a few pieces missing. These pieces are found during object design. Some of these pieces are new solution objects, adjusting off-the-shelf components, and specifying each subsystem interface and class (Bruegge and Dutiot2004).
Terms of Structured by Realized By Implemented
by by
Fig. 8.1 Software life cycle activities
System
Fig. 8.2 Object design closes the gap between the application objects and the off-the-shelf components
148 8 Object-Oriented Design
8.1.1 First Steps to OOD
Edward Berard presents the following steps as if they were sequential, some of them may be re-ordered, and some may even be accomplished in parallel.
The first part of the OOD process requires that the software engineer accom-plish two different goals: identify the objects of interest, and specify how these objects will affect a solution to the problem. A software engineer must construct an object-oriented model of the proposed solution. The object-oriented model can be accomplished using any one of a number of strategies:
(a) Writing a paragraph: Identifying the objects from the nouns, pronouns, noun phrases, adjectives etc.
(b) Constructing a graphical model using such things as semantic networks, state transition diagrams, Petri net graphs, or any other variety of diagrams.
(c) Using an automated tool to sketch a solution, e.g. Smalltalk, Trellis.
Once the strategy is agreed upon, the objects of interest can be identified. The designer should also gather information about each object and localize it with the appropriate object.
The next major step requires the designer to identify suffered and required operations for each object. A ‘‘suffered’’ operation is something which happens to a given object, e.g. adding an element to a list, directing an elevator to go up, and querying a temperature sensor as to its current value. A ‘‘required’’ operation is an operation for an object other than the encapsulating object, and is necessary to ensure the correct and desired behavior of the object. For example, if we wish a list object to be ordered, it will require that the items contained in the list furnish a
‘‘\’’ (less than) operation (Berard2002).
Object design includes four groups of activities:
ReuseClass libraries and components are selected for basic data structures and services. Design patterns are selected for solving problem and for protecting specific classes from future change. Often, components and design patterns need to be adapted before they can be used. This is done by wrapping custom objects around them or refining them by using inheritance.
Interface SpecificationDuring this activity, the subsystem services identified during system design are specified in terms of class interfaces, including opera-tions, and exceptions. The result of service specification is a complete interface specification for each subsystem. The subsystem specification is called subsystem Application Programmer Interface (API).
Restructuringactivities manipulate the system model to increase code reuse or meet other design goals. Restructuring activities include transforming n-ary associations into binary associations, implementing binary associations as refer-ences, merging two classes into a single class or collapsing classes, and rear-ranging to increase inheritance and packing.
Optimization activities address performance requirements of the system model. This includes changing algorithms to respond to speed, memory
requirements, reducing multiplicities in associations to speed up queries, rear-ranging execution order, and adding derived attributes to improve the access time to objects.
Object design is not sequential. The activities described occur concurrently.
Interface specifications and reuse activities occur first, yielding an object design model that is then checked against the use cases. Restructuring and optimization activities occur next, once the object design model for subsystem is relatively stable. Focusing on interfaces, components and design patterns result in an object design model that is easier to modify.
8.1.2 Activities in OOD
During object design our understanding of each object deepens. As the focus of system design was on identifying large chunks of work that could be assigned to individual teams or developers, the focus of object design is to specify the boundary between objects. At this stage a large number of developers refine and change many objects and their interfaces. Interface specification activities of object design include (Bruegge and Dutiot2004):
• Identifying missing attributes and operations
• Specifying type signatures and visibility
• Specifying invariants
• Specifying preconditions and postconditions
During system development we would have made decisions about the system and produced several models:
• The analysis object model describing the entity, boundary and control objects that are visible to user. The analysis object model includes attributes and operations for each object.
• Subsystem decomposition describes how these objects are partitioned into cohesive pieces that are realized by different teams of developers. Each subsystem includes high-level service descriptions that indicate which functionality it provides to others.
• Hardware/Software mapping identifies the components that make up the virtual machine on which we build solution objects. This may include classes and APIs defined by existing components.
• Boundary use cases describe, from the user’s point of view, administrative and exceptional cases that the system handles.
• Design patterns selected during object design reuse describe partial object design models addressing specific design issues.
All these models however reflect partial view of the system. The goal of the object design is to produce the object design model that integrates all of the above
150 8 Object-Oriented Design
information into a coherent and precise whole. The interface specification includes the following activities:
• Identify missing attributes and operations: During this activity, we examine each subsystem service and each analysis object.
• Specify visibility and signatures: During this activity, we decide which operations are available to other objects and subsystems and which are used only within a subsystem.
• Specify contracts: During this activity, we describe in terms of constraints the behavior of the operations provided by each object.
8.2 Object-Oriented Design Concepts
8.2.1 Functional and Non-Functional Requirements
Requirements come in two main types: functional and nonfunctional. Nonfunc-tional requirements are the requirements that are not related to how the system functions. These include, but are not limited to: performance, reliability, and aesthetics. Functional requirements on the other hand provide information on how the system operates. From the interfaces of classes to the user interface require-ments are all examples of functional requirerequire-ments.
8.2.2 Types, Signatures and Visibility
During analysis we identified attributes and operations without specifying their types or their parameters. During object design we redefine the analysis and system design models by adding type and visibility information. The type attribute specifies the range of values the attribute can take and the operations that can be applied to the attribute. For example attributes could be integer, float etc. The type of the attribute also denotes the operations we could apply, like addition or sub-traction. Given an operation, the tuple made out of the types of its parameters and the type of return value is called a signature of the operation. Visibility of an attribute or an operation specifies whether it can be used by other classes or not.
UML defines four levels of visibility:
• Private: A private attribute can be accessed only by the class in which it is defined.
• Protected: A protected attribute or operation can be accessed by the class in which it is defined and any descendent class.
• Public: A public attribute or operation can be accessed by any class.
• Package: Accessible to only other classes in the package.
Visibility is denoted in UML by prefixing the symbol—for private, # for pro-tected, + for public and * for package to the name of the attribute or operation.
8.2.3 Object Contracts: Invariants, Preconditions and Postconditions
Contracts are constraints on a class that enable the caller and callee to share the same assumptions about the class. Contracts include three types of constraints:
Invariantis a predicate that is always true for all instances of a class. Simply speaking, this is to say the class is/has/will [any word here] is a predicate. This simply allows for a description of contracts between classes.
Precondition is a predicate that must be true before an operation is invoked.
Preconditions are used to specify constraints that a caller must meet before calling operation. An example of this would be check to make sure a number that will be used to divide by is not zero, as in most instances this results in undesirable behavior.
Postcondition is a predicate that must be true after an operation is invoked.
Postconditions are used to specify constraints that the object must ensure are fulfilled after the invocation of operation (Bruegge and Dutiot2000).