The software industry and literature use the term "component" to refer to many different things. It is often used in
the broad sense to mean "a constituent part". It is also frequently used in a narrow sense to denote specific
characteristics that enable replacement and assembly in larger systems.
In the RUP, we use the term "component" to mean an encapsulated part of a system, ideally a non-trivial, nearly
independent, and replaceable part of a system that fulfills a clear function in the context of a well-defined
architecture. This includes:
-
design component - a significant encapsulated part of the design, and so includes Design Subsystems and sometimes
significant Design Classes and Design Packages.
-
implementation component - a significant encapsulated part of the implementation, generally code that implements a
design component.
Ideally the design reflects the implementation, and so one can refer to just components, each component having a design
and an implementation.
The UML ([UML04]) defines "component" as the following:
A modular part of a system that encapsulates its contents and whose manifestation is replaceable within its
environment. A component defines its behavior in terms of provided and required interfaces. As such, a component
serves as a type, whose conformance is defined by these provided and required interfaces (encompassing both their
static as well as dynamic semantics).
A component is defined as a subtype of structured class, which provides for a component having attributes and
operations, being able to participate in associations and generalizations, and having internal structure and ports.
Refer to Concept: Structured Class for more details.
A number of UML standard stereotypes exist that apply to component, e.g. <<subsystem>> to model large-scale
components, and <<specification>> and <<realization>> to model components with distinct
specification and realization definitions, where one specification may have multiple realizations.
The RUP usage of the term component is broader than the UML definition. Rather than define components as having
characteristics such as modularity, deployability, and replaceability, we instead recommend these as desirable
characteristics of components. See the section below on Component Replaceability.
In RUP and UML terminology, components should be replaceable. However, this may only mean that the component exposes a
set of interfaces that hide an underlying implementation.
There are other, stronger, kinds of replaceability. These are listed below.
Source-File Replaceability
If two classes are implemented in a single source code file, then each of the classes cannot usually be separately
versioned and controlled.
However, if a set of files fully implements a single component, and no other component, then the component is
source-file replaceable. This characteristic makes it easier for component source code to be version-controlled,
baselined, and re-used.
Deployment Replaceability
If two classes are deployed in a single executable, then each class is not independently replaceable in a deployed
system.
A desirable characteristic of larger granularity components is to be "deployment replaceable", allowing new versions of
the component to be deployed without having to re-build the other components. This usually means there is one file or
one set of files that deploy the component and no other component.
Run-Time Replaceability
If a component can be redeployed into a running system, then it is referred to as "run-time replaceable". This enables
software to be upgraded without loss of availability.
Location Transparency
Components with network addressable interfaces are referred to as having "location transparency". This allows
components to be relocated to other servers, or to be replicated on multiple servers, to support fault tolerance, load
balancing, and so on. These kinds of components are often referred to as "distributed" or "distributable" components.
The UML component is a modeling construct that provides the following capabilities:
-
can group classes to define a larger granularity part of a system
-
can separate the visible interfaces from internal implementation
-
can have instances that execute at run-time
A component has a number of provided and required Interfaces, which form the basis for wiring components together. A
provided Interface is one that is either implemented directly by the component or one of its realizing classes or
subcomponents, or it is the type of a provided Port of the Component. A required interface is designated by a Usage
Dependency from the Component or one of its realizing classes or subcomponents, or it is the type of a required Port.
A component has an external view (or "black-box" view) by means of its publicly visible properties and operations.
Optionally, a behavior such as a protocol state machine may be attached to an interface, port and to the component
itself, to define the external view more precisely by making dynamic constraints in the sequence of operation calls
explicit. The wiring between components in a system or other context can be structurally defined by using dependencies
between component interfaces (typically on component diagrams).
Optionally, a more detailed specification of the structural collaboration can be made using parts and connectors in
composite structures, to specify the role or instance level collaboration between components. That is the component's
internal view (or "white-box" view) by means of its private properties and realizing classes or subcomponents. This
view shows how the external behavior is realized internally. The mapping between external and internal view is by means
of dependencies (on components diagrams), or delegation connectors to internal parts (on composite structure diagrams).
RUP recommends using components as the representation for Design Subsystems. See Artifact: Design Subsystem, Task: Subsystem Design, and Guideline: Design Subsystem for details. Also, see definitions in Concept: Structured Class.
A component may or may not be directly instantiated at run time.
An indirectly instantiated component is implemented, or realized, by a set of classes, subcomponents or parts. The
component itself does not appear in the implementation; it serves as a design that an implementation must follow. The
set of realizing classes, subcomponents or parts must cover the entire set of operations specified in the provided
interface of the component. The manner of implementing the component is the responsibility of the implementer.
A directly-instantiated component specifies its own encapsulated implementation; it is instantiated as an addressable
object. It means that a design component has a corresponding construct in the implementation language, so it can be
explicitly referenced.
UML 1.5 defined "component" as the following:
A modular, deployable, and replaceable part of a system that encapsulates implementation and exposes a set of
interfaces. A component is typically specified by one or more classes or subcomponents that reside on it, and may
be implemented by one or more artifacts (e.g., binary, executable, or script files).
Note that in UML 1.3 and earlier versions of the UML, the "component" notation was used to represent files in the
implementation. Files are no longer considered "components" by the latest UML definitions. However, many tools and UML
profiles still use the component notation to represent files. See Guideline: Implementation Element for more discussion on representing files in the
UML.
From the modeling perspective, components were compared to UML Subsystems in UML 1.5, as they provided modularity,
encapsulation, and instances able to execute at run-time. RUP considers the UML 1.5 component modeling construct an
alternative notation for representing Design Subsystems. See Artifact: Design Subsystem and Guideline: Design Subsystem for details.
Refer to Differences Between UML 1.x and UML 2.0 for more information.
|