Task: Incorporate Existing Design Elements
This task describes how to evolve and refine the Design Model.
Disciplines: Analysis & Design
Purpose
  • To analyze interactions of analysis classes to find interfaces, design classes and design subsystems
  • To refine the architecture, incorporating reuse where possible.
  • To identify common solutions to commonly encountered design problems
  • To include architecturally significant design model elements in the Logical View section of the Software Architecture Document.
Relationships
Steps
Identify Reuse Opportunities
Purpose To identify where existing subsystems and/or components may be reused based on their interfaces. 

Look for existing subsystems or components which offer similar interfaces. Compare each interface identified to the interfaces provided by existing subsystems or components. There usually will not be an exact match, but approximate matches can be found. Look first for similar behavior and returned values, then consider parameters.

Modify the newly identified interfaces to improve the fit. There may be opportunities to make minor changes to a candidate interface which will improve its conformance to the existing interface. Simple changes include rearranging or adding parameters to the candidate interface, and then factoring the interface by splitting it into several interfaces, one or more of which match those of the existing component, with the "new" behaviors located in a separate interface.

Replace candidate interfaces with existing interfaces where exact matches occur. After simplification and factoring, if there is an exact match to an existing interface, eliminate the candidate interface and simply use the existing interface.

Map the candidate subsystem to existing components. Look at existing components and the set of candidate subsystems. Factor the subsystems so that existing components are used wherever possible to satisfy the required behavior of the system. Where a candidate subsystem can be realized by an existing component, create traceability between the design subsystem and the component in the implementation model.

In mapping subsystems onto reusable components, consider the design mechanisms associated with the subsystem; performance or security requirements may disqualify a component from reuse despite an otherwise perfect match between operation signatures.

Reverse-Engineer Components and Databases
Purpose To incorporate potentially reusable model elements from other projects, external sources or prior iterations. 

Existing code and database definitions can be 'scavenged' to make work done on previous projects or iterations available to the current project/iteration. By using potential reuse opportunities as a filter, the work that is reverse engineered can be focused on just the components which are reusable for the current iteration.

Reverse Engineer Components

In organizations which build similar systems, there is often a set of common components which provide many of the architectural mechanisms needed for a new system. There may also be components available in the marketplace which also provide the architectural mechanisms. Existing components should be examined to determine their suitability and compatibility within the software architecture.

Existing components, either developed during prior iterations but not yet included in the Design Model, or purchased components, must be reverse-engineered and incorporated into the Design Model. In the Design Model, such components are commonly represented as a Subsystem with one or more Interfaces.

Reverse Engineer Databases

Databases, and the data residing in them, represent one of the most important sources for reusable assets. To reuse the implicit class definitions embodied in existing databases, determine which information used by the application already resides in existing databases. Reverse-engineer a set of classes to represent the database structures that hold this information. At the same time, construct a mapping between the application's class representation and the structures used in the database. For more information on reverse engineering databases, see  Guideline: Reverse-engineering Relational Databases. For more on mapping between classes and tables in a relational database, see  Guideline: Data Model.

Update the Organization of the Design Model
Purpose To account for the new model elements in the organization of the Design Model.
To re-balance the structure of the Design Model where necessary. 

As new elements have been added to the Design Model, re-packaging the elements of the Design Model is often necessary. Repackaging achieves several objectives: it reduces coupling between packages and improves cohesion within packages in the design model. The ultimate goal is to allow different packages (and subsystems) to be designed and developed independently of one another by separate individuals or teams. While complete independence is probably impossible to achieve, loose coupling between packages tends to improve the ease of development of large or complex systems.

A 'flat' model structure (where all packages and subsystems reside at the same conceptual level in the system) is suitable for a small system; larger systems need an additional structuring tool called 'layering' (see Guideline: Layering). Layering rules define restrictions on allowed relationships between certain types of packages. These rules recognize that certain dependencies should not exist: application functionality should not be directly dependent on specific operating system or windowing system services - there should be an intermediate layer containing logical operating system and windowing services that insulate the application functionality from changes in low-level implementation services. Layering provides a way to reduce the impact of change: by enforcing rules which restrict the dependencies between packages and subsystems, reducing the degree of coupling between packages and subsystems, the system becomes more robust. It tolerates change.

As new model elements are added to the system, existing packages may grow too large to be managed by a single team: the package must be split into several packages which are highly cohesive within the package but loosely coupled between the packages. Doing this may be difficult - some elements may be difficult to place in one specific package because they are used by elements of both packages. There are two possible solutions: split the element into several objects, one in each package (this works where the element has several 'personalities', or sets of somewhat disjoint responsibilities), or move the element into a package in a lower layer, where all higher layer elements may depend upon it equally.

As the system grows in complexity, a larger number of layers will be needed in order to have a maintainable and understandable structure. More than 7-10 layers, however, are unusual in even the largest systems, since complexity increases and understandability decreases with the number of layers.

An example of layering, including middle-ware and System-software layers, is shown below:

Layout Diagram for a Java/Web application

Sample package layering for a Java/Web-based application. Note: the dependencies on the TCP/IP package would not normally be explicitly modeled as the use of TCP/IP services is encapsulated within the Java VM, java.rmi and the Web Browser. They are depicted here only for illustration.

Assign responsibilities for the subsystems and layers to individuals or teams. Each package or subsystem should be the responsibility of a single person (if its scope is small) or a team (if its scope is large).

Update the Logical View
Purpose To ensure that the Work Product: Software Architecture Document (Logical View) remains up to date. 

When design classes, packages and subsystems (model elements) are important from an architectural perspective, they should be included in the Logical View section of the Artifact: Software Architecture Document. This will ensure that new architecturally significant model elements are communicated to other project team members.

In addition, the software architect role collaborates with the process engineer role to provide detailed guidance to designers and implementers on how to use the newly incorporated design elements.