Decomposition Style

2.1.1 Overview

By taking the elements and the properties of the module viewtype and focusing on the is-part-of relation, we get the module decomposition style. You can use this style to show how system responsibilities are partitioned across modules and how those modules are decomposed into submodules. Unlike other styles of the module viewtype, decomposition features fairly weak restrictions on the viewtype itself but is usefully distinguished as a separate style, for several reasons.

First, almost all architectures begin with the module decomposition style. Architects tend to attack a problem with divide-and-conquer techniques, and a view rendered in this style records their campaign. Second, a view in this style is a favorite tool with which to communicate the broad picture of the architecture to newcomers. Third, this style begins to address the modifiability that will be built into the architecture by allocating functionality to specific places in the architecture.

The criteria used for decomposing a module into smaller modules depend on the purpose of the decomposition:

A decomposition view may represent the first pass at a detailed architectural design; the architect may subsequently introduce other style-based specializations and evolve the view resulting from decomposition into a more detailed use, layered, or other module-based view in some other style.

2.1.2 Elements, Relations, and Properties

Table 2.1 summarizes the discussion of the characteristics of the decomposition style. Elements of the decomposition style are modules, as described in Section 1.2. Certain aggregations can be called subsystems. The principal relation, the decomposition relation, is a specialized form of the is-part-of relation and has as its primary constraint the guarantee that an element can be a part of at most one aggregate.

The decomposition relation may have a visibility property, which defines whether the submodules are visible to only the aggregate modulethe parentor also to other modules. A module is said to be visible if it can be used by other modules. With this property, an architect has some control over the visibility of modules, as illustrated in Figure 1.1. A decomposition relation in which no contained module is visible outside its parent is sometimes called a containment relation. In a decomposition relation, loops are not allowed; that is, a module cannot contain any of its ancestors. No module in a decomposition view can have more than one parent.

Table 2.1. Summary of the module decomposition style

Elements Module, as defined by the module viewtype. A module that aggregates other modules is sometimes called a subsystem.
Relations The decomposition relation, which is a refined form of the is-part-of relation. A documentation obligation includes specifying the criteria used to define the decomposition.
Properties of elements As defined by the module viewtype.
Properties of relations Visibility, the extent to which the existence of a module is known, and its facilities are available, to those modules outside its parent.
Topology
  • No loops are allowed in the decomposition graph.
  • A module cannot be part of more than one module in a view.

2.1.3 What the Decomposition Style Is For and What It's Not For

A decomposition style view presents the functionality of a system in intellectually manageable pieces that are recursively refined to convey more and more details. Therefore, this style is well suited to support the learning process about a system. Besides the obvious benefit for the architect to support the design work, this style is an excellent learning and navigation tool for newcomers in the project or other people who do not necessarily have the whole functional structure of the system memorized. The grouping of functionality shown in this style also builds a useful basis for defining configuration items within a configuration management framework.

The decomposition style most often serves as the input for the work assignment view of a system, which maps parts of a software system onto the organizational units, or teams, that will be given the responsibility for implementing and testing them. A decomposition view also provides some support for analyzing effects of changes at the software implementation level, but because this view does not show all the dependencies among modules, you cannot expect to do a complete impact analysis. Here, views that elaborate the dependency relationships more thoroughly, such as the module uses style described later, are required.

2.1.4 Notations for the Decomposition Style

Informal Notations

In informal notations, modules in the decomposition style are usually depicted as named boxes that contain other named boxes. Containment can also be shown using indentation, as in Figure 2.2.

Figure 2.2. The decomposition of the A-7E software architecture results in three modules and is-part-of relations (Bass, Clements, Kazman, 2001, p. 61).

The nesting notation can use a thick border suggesting opaquenessand explained in the keyindicating that children are not visible outside the parent. Similarly, various kinds of arcs can be used to indicate containment, or nonvisibility, as opposed to an ordinary is-part-of relation. If a visual notation is not available for indicating visibility, it can be defined textually, as is done for other properties, especially the modules' responsibilities.

UML

In UML, the subsystem construct can be used to represent modules that contain other modules; the class box is normally used for the leaves of the decomposition. Subsystems are both a package and a classifier. As a package, they can be decomposed and hence are suitable for the aggregation of modules. As a classifier, they encapsulate their contents and can provide an explicit interface.

In UML, aggregation is depicted in one of three ways:

  1. Modules may be nested, as in Figure 2.1(a).

    Figure 2.1. In UML, aggregation may be shown by (a) nesting, with the aggregate module shown as a package, or by (b) using arcs between the parent and the children. The solid diamond indicates the parent module.

  2. A succession of two diagrams, possibly linked, can be shown, with the second a depiction of the contents of a module shown in the first.
  3. An arc denoting composition may be drawn between the parent and the children, as in Figure 2.1(b). In UML, composition is a form of aggregation with implied strong ownership. That is, parts live and die with the whole. If module A is composed of modules B and C, for example, B or C cannot exist without the presence of A. If A is destroyed at runtime, so are B and C. Thus, UML's composition relation has implications beyond the structuring of the implementation units; the relation also endows the elements with a runtime property. As an architect, you should make sure that you are comfortable with this property before using UML's composition relation.

Other properties, such as the modules' responsibilities, are given textually, perhaps using an annotation.

2.1.5 Relation to Other Styles

It is possible, and often desirable, to map between a module decomposition view and a component-and-connector view. We discuss this in greater detail later. For now, it is sufficient to say that the point of providing such a mapping is to indicate how the software implementation structures map onto runtime structures: generally, a many-to-many relationship. The same module might implement several components or connectors. Conversely, one component might require several modules for its implementation. The mapping may be fairly straightforward or quite complex.

The decomposition style is closely related to the work assignment style, a member of the allocation viewtype. The work assignment style maps modules resulting from a decomposition to a set of teams responsible for implementing and testing those modules.

2.1.6 Examples of the Decomposition Style

ECS

Appendix A contains an example of a module decomposition view for NASA's ECS system.

A-7E Avionics System

An example of the decomposition style comes from the A-7E avionics software system described in Bass, Clements, and Kazman 1998, Chapter 3. Figure 2.2 shows the graphical part of the view. The figure names the elements and shows the is-part-of relation among them for the A-7E system.

Except for the modules' names, however, the figure shows none of the properties associated with this style. Supporting the figure is textual documentation that explains the decomposition criteria and for each module lists

In this example, the criterion for decomposition is the information-hiding principle, which holds that there should be a module to encapsulate the effects each kind of change considered likely. A module's responsibilities, then, are described in terms of the information-hiding secrets it encapsulates.

In A-7E, the first-order decomposition produced three modules: hardware hiding, behavior hiding, and software decision hiding. Each of these modules is decomposed into two to six submodules, which are in turn decomposed, and so forth, until the granularity is fine enough to be manageable. A useful design heuristic holds that a module is small enough if it could be discarded and begun again if the programmer(s) assigned to implement it left the project.

The A-7E module view documentation describes the responsibilities of the three highest-level modules as follows:

Following is how the documentation describes the decomposition of the Software Decision Module into second-level modules. Unless otherwise indicated, a module is visible outside its parent:

In the case of the A-7E architecture, this second-level module structure was enshrined in many ways: Design documentation, online configuration-controlled files, test plans, programming teams, review procedures, and project schedule and milestones all were pegged to this second-level module structure as their unit of reference. If you use a module decomposition structure to organize your project, you need to pick a level of the hierarchy as was done here, based on a granularity of modules that is manageable. The module guide describes a thirdand in some cases a fourthlevel of decomposition, but that has been omitted here.

Mil-Std 498 CSCIs and CSCs

Readers familiar with U.S. military software standards, such as MIL-STD-498 and MIL-STD-2167A, will recognize that CSCIs (Computer Software Configuration Items), and CSCs (Computer Software Components) constitute a decomposition view of a system and nothing more. A CSCI is an aggregation of software that satisfies an end use function and is designated for separate configuration management by the acquirer. CSCIs are selected based on trade-offs among software function, size, host or target computers, developer, support concept, plans for reuse, criticality, interface considerations, the need to be separately documented and controlled, and other factors. A CSC is a distinct part of a CSCI and may be further decomposed into other CSCs and CSUs (Computer Software Units).

COMING TO TERMS

Subsystem

When documenting a module view of a system, you may choose to identify certain aggregated modules as subsystems. A subsystem can be pretty much anything you want it to be, but it often describes a part of a system that (1) carries out a functionally cohesive subset of the overall system's mission, (2) can be executed independently, and (3) can be developed and deployed incrementally. An air traffic control system, for example, may be divided into the following areas of capability:

  • Interpreting radar data to display aircraft positions on screens
  • Detecting aircraft that are about to violate separation constraints
  • Running simulations for training
  • Recording and playback for after-situation analysis and training
  • Monitoring its own health and status

Each of these areas might reasonably be called a subsystem. Informally, a subsystem refers to a system portion that can be usefully considered separately from the other portions.

But not just any portion of a system will do. At a minimum, a subsystem must exhibit some coherent, useful functionality. More than that, however, the term also suggests a portion of the system that can execute more or less independently and that directly supports the system's overall purpose. In our air traffic control application, for example, a math utilities library is certainly a portion of a system and an aggregation of modules and even has coherent functionality. But the library is unlikely to be called a subsystem, because it lacks the ability to operate independently to do work that's recognizably part of the overall system's purpose.

Subsystems do not partition a system into completely separate parts, because some parts are used in more than one subsystem. For example, suppose that the air traffic control system looks like this:

In this case, a subsystem consists of one segment from the top layer, as well as any segments of any lower layers that it needs in order to carry out its functionality. A subset of the system formed in this way is often called a slice, or a vertical slice.

The "more or less independent" nature of a subsystem makes it ideal for dividing up a project's work. You may, for example, ask an analyst to examine the performance of a subsystem. If a user's interaction with a system can be confined to a subsystem, its security properties become important. A subsystem can often be fielded and accomplish useful work before the whole system is complete. A subsystem makes a convenient package to hand off to a team or a subcontractor to implement. The fact that it executes more or less independently allows that team to work more or less independently even through testing. An arbitrary module, by contrast, can certainly be assigned to a team for implementation, but it probably requires the presence of other modules to see it through testing.

The UML world has co-opted the term subsystem to mean something quite specific: an aggregation of elements that exhibits behaviorthe collective behavior of the aggregated elementsand possibly offering one or more interfacesrealized by the interfaces of the aggregated elements. According to the UML specification:

A subsystem is a grouping of model elements, that represents a behavioral unit in a physical system. . . . The contents of a Subsystem are divided into two subsets: specification elements and realization elements. The former provides, together with the Operations of the Subsystem, a specification of the behavior contained in the Subsystem, while the ModelElements in the latter subset jointly provide a realization of the specification. . . . The purpose of the subsystem construct is to provide a grouping mechanism for specifying a behavioral unit of a physical system. . . . The contents of a subsystem are defined in the same way as for a package. . . . A subsystem has no behavior of its own. All behavior defined in the specification of the subsystem is jointly offered by the elements in the realization subset of the contents. . . . A subsystem may offer a set of interfaces. This implies that for each operation defined in an interface, the subsystem offering the interface must have a matching operation, either as a feature of the subsystem itself or of a specification element. The relationship between interface and subsystem is not necessarily one-to-one.

The observation that a subsystem has no behavior or interface of its own except for that of its aggregated parts corresponds to Figure 1.1(b). In UML, the notation for subsystems is based on the package construct. Any of the following are correct:

You may decide to identify subsystems in your design. If you do, make sure that your rationale explains why you chose the ones you did and what you plan to do with them.

Категории