The assumption is that subsystems, by default, can operate autonomously and concurrently with other subsystems (that
is, they encapsulate one or more independent loci of control). Thus, it is a design decision whether additional
processes (active classes) that are not encapsulated in subsystems are defined at this level. For example, whether
active (boundary) classes are needed to drive and respond to external interfaces, or whether active control classes are
needed to coordinate the actions of subsystems, or whether, at this level only subsystems appear. A rule of thumb is
that there be at least one thread of control within the system, for each interface offered by a system (or subsystem),
but these threads of control might themselves be encapsulated (within subsystems). Processes (and associated
threads) are rooted in active classes; and instances of these (as active objects), not encapsulated in
subsystems, can appear in interaction diagrams with subsystem instances, as shown below.
Note that the active classes Operator Keyboard, Operator Display and Printer, Laser Scanner and Magnetic Stripe Reader
could be encapsulated within the subsystem Point-of-Sale Control, exposing these at the system level could be driven,
for example, by their perceived importance, deployment issues, or the need to use them in some other application (which
would indicate that the active classes are not simply "dumb" device drivers).
Just as interesting as the existence of an active object and whether particular subsystems are, for some interactions
at least, passive, is the sequence or path of a process (or thread). An invoked operation can, in turn, invoke others
(in other subsystems) using the same process, and possible delays (waiting for resources, for example) might be
critically important to the System Architect, if processes have deadlines to meet. Repartitioning the subsystems might
lead the System Architect to reconsider the process structure.
|