Guidelines: Design Subsystem

Design Subsystem
|
A
model element which has the semantics of a package (it can contain other model elements)
and a class (it has behavior). The behavior of the subsystem is provided by classes
or other subsystems it contains. A subsystem realizes one or more interfaces, which
define the behavior it can perform. |
Topics
Subsystems can be used in a number of
complementary ways, to partition the system into units which:
- can be independently ordered, configured, or delivered
- can be independently developed, as long as the interfaces remain unchanged
- can be independently deployed across a set of distributed computational nodes
- can be independently changed without breaking other parts of the systems
In addition, subsystems can:
- partition the system into units which can provide restricted security over key resources
- represent existing products or external systems in the design
If the classes in a collaboration interact only with each other to produce a
well-defined set of results, the collaboration and its classes should be encapsulated
within a subsystem.
This rule can be applied to subsets of collaborations as well. Anywhere part or
all of a collaboration can be encapsulated and simplified, doing so will make the design
easier to understand.
Hints
Hint
|
Details |
Look for optionality |
If a particular collaboration (or sub-collaboration) represents
optional behavior, enclose it in a subsystem. Features which may be removed,
upgraded, or replaced with alternatives should be considered independent. |
Look to the user interface of the
system. |
If the user interface is relatively independent of the entity
classes in the system (i.e. the two can and will change independently), create subsystems
which are horizontally integrated: group related user interface boundary classes together
in a subsystem, and group related entity classes together in another subsystem. |
If the user interface and the entity classes it displays are
tightly coupled (i.e. a change in one triggers a change in the other), create subsystems
which are vertically integrated: enclose related boundary and entity classes in common
subsystem. |
Look to the Actors |
Separate functionality used by two different actors, since each
actor may independently change their requirements on the system. |
Look for coupling and cohesion between classes |
Highly coupled or cohesive classes collaborate to provide some
set of services. Organize highly coupled classes into subsystems, separating classes
along lines of weak coupling. In some cases, weak coupling can be eliminated
entirely by splitting classes into smaller classes with more cohesive responsibilities. |
Look at substitution |
If there are several levels of service specified for a
particular capability (example: high, medium and low availability), represent each service
level as a separate subsystem, each of which will realize the same set of
interfaces. By doing so, the subsystems are substitutable for one another. |
Look at distribution |
If particular functionality must reside on a particular node
(such as a client workstation, or a particular device), ensure that the subsystem
functionality maps onto a single node. Split subsystems into several nodes, where
necessary, in order to achieve this. |
Once classes have been organized into subsystems, update the Use Case Realizations
accordingly.
Once the subsystem has been created:
- Each subsystem must be given a name and a short description.
- Where tools support packages but not subsystems, packages can be used to document
subsystems; the package stereotype <<subsystem>> should be used to denote a
subsystem in this context.
- The responsibilities of the original analysis class should be transferred to the
newly-created subsystem, using the description of the subsystem to document the
responsibilities.
Components are implementation things; to represent the component in the design, a
subsystem can be used as a proxy for the component.
- Each part of the system should be as independent as possible from other parts of the
system.
- Ideally, it should be possible to replace any part of the system with a new part,
provided the new part supports the same interfaces.
- It should be possible to evolve different parts of the system independently from other
parts of the system.
To this end, Design Subsystems provide an ideal way to represent components in the
Design Model: they are design elements which encapsulate the behavior of a number of
classes (as components encapsulate the behavior of a number of class instances), and their
behavior is only accessed via the interfaces they realize (as is the case with
components).
Examples of products the system uses that you can represent by a subsystem include:
- Communication software (middle-ware).
- Database access support (RDBMS mapping support).
- Types and data structures (stacks, lists, queues).
- Common utilities (math libraries).
- Application-specific products.
When defining the subsystem to represent the product, also define one or more
interfaces to represent the product interfaces.
Subsystems differ from packages in their semantics: a subsystem is a kind of package
which provides behavior through one or more interfaces which it realizes. Packages
provide no behavior; they are simply containers of things which provide behavior.
The reason for using a subsystem instead of a package is that subsystems completely
encapsulate their contents, providing behavior only through their interfaces. The
benefit of this is that, unlike a package, the contents and internal behaviors of a
subsystem can change with complete freedom so long as the subsystem's interfaces remain
constant. Subsystems also provide a 'replaceable design' element: any two subsystems
(or classes, for that matter) which realize the same interfaces are interchangeable.
In order to ensure that subsystems are replaceable elements in the model, a few rules
need to be enforced:
- A Subsystem should not expose any of its contents (i.e. no element contained by a
subsystem should have 'public' visibility); no element outside the subsystem should depend
on the existence of a particular element inside the subsystem.
- A Subsystem should only depend on the interfaces of other model elements, so that it is
not directly dependent on any specific model elements outside the subsystem. The
exceptions are cases where a number of subsystems share a set of class definitions in
common, in which case those subsystems 'import' the contents of the packages which contain
the common classes. This should only be done with packages in lower layers in the
architecture, and only to ensure that common definitions of classes which must pass
between subsystems are consistently defined.
An example of Subsystem and Package dependencies is shown below:

Subsystem and Package Dependencies in the Design Model
| |

|