Introduction
Moving from the Analysis to the Design level of the architecture entails determination of the hardware and
software component design. This Design-level specification consists of the components to be deployed:
hardware, software, and workers.
Hardware components are determined by analyzing the localities, their derived characteristics, and hosted
subsystem operations. With this information, Descriptor-level realizations of the localities can be
selected. Descriptor node diagrams specify the components, servers, workstations, workers, and so forth,
without specific choices of technologies that implement those components. The figure is an example
Descriptor node diagram that realizes the Locality diagram shown in Concept: Locality. The fulfillment Locality is realized as four
components: a warehouse gateway and mailing/postage system, and two workers.
The Descriptor nodes inherit characteristics from their localities through an allocation or budgeting
process.
Hardware
The implementation hardware components, the actual deployed set of hardware, are determined by making
cost/performance/capacity trades from the Descriptor view. In fact, a system might have more than one
hardware configuration, each meeting different price/performance points.
Software
Components are determined by specifying a set of classes, and then compiling and assembling the code
associated with those classes into executable files. A fully considered software component design must
reflect a variety of concerns:
-
Locality—where the components need to run
-
Hosting—processor instruction set and memory restrictions for the executing code
-
Concurrency—separation of processing into different hosts or memory spaces to address reliability
and related concerns
It follows that the information needed to specify components includes the surveys of hosted subsystem
operations for localities and their realized hardware components, surveys of executed operations for
processes, along with collaborations, realizing the subsystem operations, which yield the set of classes to
be formed into a component structure.
As a first approximation, assume all classes reside in a single component, giving a one-to-one mapping of
component and subsystem—this is the default advice given in Guideline: Design Subsystem. Next, look for reasons to
partition the component further. If the set of classes contains more than one active class, representing a
process, then examine a partitioning of one active class (process) per component, clustering those classes
with the strongest relationships. Some classes can then be used by multiple components. If any of these
classes represent shared state in a common set of instances that are to be accessed by several components,
then there is a case to split them off into another component of their own. If the shared classes are
stateless, you might choose to separate them out into a service component (a stateless functional
component), if they are functionally cohesive. Even in a passive subsystem (no active classes), you can
still choose to partition further, for example, looking for finer-grained components that are reusable.
Complete the process by repartitioning/dividing the components further to account for specific technology
choices (such as the J2EE™ platform, or Microsoft® .NET), memory constraints (such as .exe and
.dll trade-offs), shipping media limitations, and so forth.
These tasks result in a set of specific hardware and software components that
make up the system.
|