As a model may have hundreds (if not thousands) of model elements, how do you organize the elements that make up a system and their relationships? And how do you use this information to determine how best to develop the system while considering technical trade-offs concerning the system, including which elements may be developed in parallel, which elements may be purchased rather than built, and which elements may be reused? Packages and subsystems, called model management elements, address these questions.
A package is a grouping and organizing element in which other elements reside, which must be uniquely named. In the UML, packages are used in a manner similar to the way directories and folders in an operating system group and organize files. For example, the project management system may be decomposed into a collection of classes organized into packages as follows:
Utility
Workers
The Worker
class and
any
other worker-related classes in which the Worker
class is contained inside of a package named
Generic
Generic
Generic classes such as
the
Worker
class and any other worker-related classes
Work Units
Work Products
The WorkProduct
class and
any other work product-related classes
User Interface
A package housing classes responsible for providing a user interface through which users may interact with the system
Business Processing
A package housing classes responsible for implementing business functionality
Data
A package housing classes responsible for implementing data storage functionality
Packages allow us to partition our system into logical groups and then to relate these logical groups; otherwise, it could become overwhelming to work with every class and its relationship at once. A package is shown as a large rectangle with a small rectangle or “tab” attached to its top, left side. The packages in the previous list, together with their relationships, are shown in Figure 3-41.
You can show the name of a package inside of its large rectangle when
the package contents are not shown; otherwise, when the package
contents are shown in the large rectangle, you should show the name
of a package inside its tab. In Figure 3-41, you see
that the User
Interface
,
Utility
, and Business
Processing
packages don’t show
their contents, while all the other packages do show some of their
contents. Thus, the User
Interface
, Utility
, and
Business
Processing
packages
have their package names within the large rectangle, whereas the
other packages have their names in their respective tabs. Each
element inside a package may have a visibility symbol indicating
whether the element is accessible from outside its package (i.e., is
public). Figure 3-41 shows that the
Worker
, UnitOfWork
, and
WorkProduct
classes are public. The
Generic
package located inside of the
Workers
package is also public.
A dependency from a source
package
to a target package indicates that the contents of the source package
use the contents of the target package. Figure 3-41
shows that the Data
package uses the
Workers
, Work
Units
, and Work
Products
packages. It also shows that the
User
Interface
,
Business
Processing
, and
Data
packages use the Utility
package, while the User
Interface
package uses the
Business
Processing
package,
which in turn uses the Data
package.
A package defines a namespace, a
part
of a model in which a name must be unique. An element shown in a
package is most likely defined in that package if it is simply named.
For example, the Work Units
package in Figure 3-41 defines one public class named
UnitOfWork
. You can show the
UnitOfWork
class in other packages to indicate
that those packages use the class, in which case you qualify the
class name with the path to the package in which the class is
defined. Such a fully qualified name is referred to as a pathname.
The pathname of an element
is
a sequence of package names linked together and separated by double
colons (:
:), followed by the name of the element.
The sequence of package names starts from the outermost package level
and works its way down to the package containing the element in
question. Figure 3-41 shows that the
Data
package uses the following:
Workers::Generic::Worker
The Worker
class located inside the
Generic
package, which is nested inside the
Workers
package
Work Units::UnitOfWork
The UnitOfWork
class located inside the
Work Units
package
Work Products::WorkProduct
The WorkProduct
class located inside the
Work Products
package
Recall that a system is an organized collection of elements that may be recursively decomposed into smaller subsystems and eventually into nondecomposable primitive elements. For example, the project management system may be decomposed into the following:
A user interface subsystem responsible for providing a user interface through which users may interact with the system
A business processing subsystem responsible for implementing business functionality
A data subsystem responsible for implementing data storage functionality
The primitive elements would be the various classes that are used in these subsystems and ultimately in the whole system. While a package simply groups elements, a subsystem groups elements that together provide services such that other elements may access only those services and none of the elements themselves. And while packages allow us to partition our system into logical groups and relate these logical groups, subsystems allow us to consider what services these logical groups provide to one another.
A subsystem is shown as a package
marked
with the subsystem
keyword. The large package
rectangle may have three standard compartments shown by dividing the
rectangle with a vertical line and then dividing the area to the left
of this line into two compartments with a horizontal line. Figure 3-42 shows how a Data
subsystem
for our project management system might look. The
subsystem’s operations, specification elements, and
interfaces describe the services the subsystem provides, and are the
only services accessible by other elements outside the subsystem.
The upper-left compartment shows a list of operations that the subsystem realizes. The lower-left compartment may be labeled “Specification Elements” and shows specification elements that the subsystem realizes. For example, any use cases that the subsystem provides are specification elements that the subsystem must realize. The right compartment may be labeled “Realization Elements” and shows elements inside the subsystem that realize the subsystem’s operations and specification elements as well as any interfaces that the subsystem provides. You can modify this general notation by rearranging compartments, combining compartments, or completely suppressing one or more compartments. Any element may be used as a specification or realization element, because a realization simply indicates that the realization element supports at least all the operations of the specification element without necessarily having to support any attributes or associations of the specification element.
Figure 3-43 uses subsystems to refine Figure 3-41. The Business Processing
and Data
packages from Figure 3-41 are now subsystems. The Business Processing
subsystem provides an interface that is used by
the User
Interface
package. The
Business
Processing
subsystem
itself uses the Data
subsystem and the
IProducible
interface provided by the
Data
subsystem. The Data
subsystem realizes the IProducible
interface,
which is outside the subsystem itself, various operations, and the
Manage
Project
use case that
was discussed in Chapter 2. The use case is the
oval in the specification element’s compartment. The
realization elements of the Data
subsystem realize
the read
, destroy
, and
doWork
operations, the use case, and the
operations of the IProducible
interface.
Notice in Figure 3-43 that the
User
Interface
package does not
use the Business
Processing
package as shown in Figure 3-41, but instead uses
the IBusinessProcessing
interface provided by the
Business
Processing
subsystem.
This use of an interface allows us to focus on the service that the
User Interface
package uses rather than on the
package providing the service. If you focus on the fact that the
User Interface
package uses the
Business
Processing
package,
you are unaware of the exact operations the User
Interface
package requires from the
Business
Processing
package; if
there is a change to the Business
Processing
package, you would have to expend
significant effort to determine whether the change requires modifying
the User
Interface
package. By
focusing on the service that the User
Interface
package uses rather than the package
providing the service, you are aware of the exact operations used
from the package providing the service; only if there is a change to
the service or to those operations do you have to expend effort to
determine whether the change requires modifying the
User
Interface
package. Rather
than having to consider all the operations available inside the
Business
Processing
package to
determine whether changes to that package impact the
User
Interface
package, you
need only look at a subset of those operations: the subset defined by
the IBusinessProcess
interface. Similarly, notice
how the Business
Processing
package uses the Data
package in Figure 3-41, but the Business
Processing
subsystem uses the operations,
specification elements, and IProducible
interface
provided by the Data
subsystem in Figure 3-43.
Figure 3-43 shows the major elements that make up the project management system and the relationships between them. Using packages, subsystems, interfaces, and their relationships, you can more readily consider which elements may be developed in parallel, which elements may be purchased rather than built, and which elements may be reused. It is possible to address these issues with classes and their relationships, but because a system may have many classes, it can easily become overwhelming to work with such granularity. You could also address these issues by using packages and their dependencies, but packages don’t offer services. Packages simply capture the major elements that make up a system and not the services that are being used from a package. Thus, you must focus on all the contents of a package rather than on the services used by elements that depend on the package. However, by using packages, subsystems, interfaces, and their relationships, you can more readily address the issues listed earlier, because you capture the major elements making up the system, as well as the services that are provided and required for these elements to work together to provide the functionality of the system.
Because a subsystem’s operations, specification
elements, and interfaces describe the services the subsystem
provides, which are the only services accessible by other elements
outside the subsystem, any collection of subsystems may be developed
in parallel, because any interdependencies between them rely only on
their services. For example, you may develop the
Data
subsystem and Business Processing
subsystem in parallel, because any elements that
use these subsystems always use the defined services.
Because a subsystem’s services are fully specified,
you can attempt to search for and purchase (rather than build) a
subsystem that provides the same services. For example, you may not
have enough funding to build the Data
subsystem,
but because you know the services of the subsystem, you can attempt
to search and purchase a similar subsystem that offers the same
services.
Because a subsystem’s services are fully specified,
you can reuse the subsystem whenever you require similar services.
For example, whenever you require services defined by the
IBusinessProcessing
interface, you can reuse any
subsystem that provides the interface; whenever you require services
defined by the IProducible
interface, the
read
operation, the destroy
operation, the doWork
operation, or the
Manage
Project
use case, you
can reuse any subsystem that provides any of these services.
18.217.60.35