A component is a physical replaceable part of a system that complies with and provides the realization of a set of interfaces. We use components to model the physical things that may reside on a node, such as executables, libraries, tables, files and documents. A component typically represents the physical packaging of otherwise logical elements such as classes, interfaces and collaborations.
We do logical modeling to visualize, specify, and document our decisions about the vocabulary of our domain and the structural and behavioral way those things collaborate. We do physical modeling to construct the executable system. Object libraries, executables, COM+ components and Enterprise Java Beans are all examples of components.
Components and Classes
In many ways, components are like classes. Both have names, both may realize a set of interfaces, both may participate in dependency, generalization and association relationships, both may be nested, and both may have instances. However, there are some significant differences between components and classes:
- Classes represent logical abstractions, components represent physical things that live in the world of bits. In short, components may live on nodes, classes may not.
- Components represent the physical packaging of otherwise logical components and are at a different level of abstraction.
- Classes may have attributes and operations directly. In general, components only have operations that are reachable only through their interfaces.
The relationship between a component and the classes it implements can be shown explicitly by using a dependency relationship as shown below:
Components and Interfaces
An interface is a collection of operations that are used to specify a service of a class or a component. We can show the relationship between a component and its interfaces in one of the two ways. The first style renders the interfaces in its elided, iconic form. The component that realizes the interfaces is connected to the interface using an elided realization relationship. The second style renders the interface in its expanded form, perhaps revealing its operations. The component that realizes the interface is connected to the interface using a full realization relationship. In both cases, the component that accesses the services of the other component through the interfaces is connected to the interface using a dependency relationship.
The basic intent of every component-based operating system facility is to permit the assembly of systems from binary replaceable parts. This means that we can create a system out of components and then evolve the system by adding new components and replacing the old ones, without rebuilding the system.
First, a component is physical. It lives in the world of bits, not concepts.
Second, a component is replaceable. A component is substitutable means it is possible to replace a component with another that conforms to the sane interfaces.
Third, a component is part of a system. A component rarely stands alone. Rather, a given component collaborates with other components and in so doing exists in the architectural or technology context in which it is intended to be used.
Fourth, a component conforms to and provides the realization of a set of interfaces.
Kinds of Components
Three kinds of components may be distinguished.
First, there are deployment components. These are the components necessary and sufficient to form an executable system, such as dynamic libraries (DLLs) and executables (EXEs).
Second, there are work product components. These components are generally the residue of the development process, consisting of things such as the source code files and data files from which deployment components are created.
Third are execution components. These components are created as a consequence of an executing system, such as COM+ object, which is instantiated from a DLL.
All the UML’s extensibility mechanisms apply to components. Most often, we’ll use tagged values to extend the component properties and stereotypes to specify new kind of components.
The UML defines five standard stereotypes that apply to components:
Common Modeling Techniques
Modeling Executables and Libraries
To model executables and libraries:
- Identify the partitioning of the physical system. Consider the impact of the technical, configuration management and reuse issues.
- Model any executables and libraries as components, using the appropriate standard elements.
- Model the significant interfaces that some components use and others realize.
- As necessary to communicate your intent, model the relationships among these executables, libraries and interfaces.
Modeling Tables, Files and Documents
To model tables, files and documents:
- Identify the components that are part of the physical implementation of your system.
- Model these things as components.
- As necessary to communicate your intent, model the relationships among these components and other executables, libraries and interfaces in the system.
Modeling an API
To model an API:
- Identify the programmatic seems in the system and model each seem as an interface.
- Expose only those properties of the interface that are important to visualize the given context. Otherwise, hide these properties, keeping them in the interface’s specification for reference, as necessary.
- Model the realization of each API only as it is important to show the configuration of a specific implementation.
Modeling Source Code
To model source code:
- Depending on the constraints imposed by your development tools, model the files used to store the details of all your logical elements, along with their compilation dependencies.
- Use tagged values if you want to use configuration management and version control tools.
- As far as possible, let your development tools manage the relationships among these files, and use the UML only to visualize and document these relationships.