Domain engineering provides the library of reusable components that are required for component-based software engineering. Some of these reusable components are developed in-house, others can be extracted from existing applications, and still others may be acquired from third parties. Unfortunately, the existence of reusable components does not guarantee that these components can be integrated easily or effectively into the architecture chosen for a new application. It is for this reason that a sequence of component-based development activities are applied when a component is proposed for use.
Component qualification ensures that a candidate component will perform the function required, will properly “fit” into the architectural style specified for the system, and will exhibit the quality characteristics (e.g., performance, reliability, usability) that are required for the application.
The interface description provides useful information about the operation and use of a software component, but it does not provide all of the information required to determine if a proposed component can, in fact, be reused effectively in a new application.
Among the many factors considered during component qualification are:
• Application programming interface (API).
• Development and integration tools required by the component.
• Run-time requirements, including resource usage (e.g., memory or storage), timing or speed, and network protocol.
• Service requirements, including operating system interfaces and support from other components.
• Security features, including access controls and authentication protocol.
• Embedded design assumptions, including the use of specific numerical or nonnumerical algorithms.
• Exception handling.
Each of these factors is relatively easy to assess when reusable components that have been developed in-house are proposed. If good software engineering practices were applied during their development, answers to the questions implied by the list can be developed. However, it is much more difficult to determine the internal workings of COTS or third-party components because the only available information may be the interface specification itself.
In an ideal setting, domain engineering creates a library of components that can be easily integrated into an application architecture. The implication of “easy integration” is that (1) consistent methods of resource management have been implemented for all components in the library, (2) common activities such as data management exist for all components, and (3) interfaces within the architecture and with the external environment have been implemented in a consistent manner.
In reality, even after a component has been qualified for use within an application architecture, it may exhibit conflict in one or more of the areas just noted. To mitigate against these conflicts, an adaptation technique called component wrapping is often used. When a software team has full access to the internal design and code for a component (often not the case when COTS components are used) white-box wrapping is applied. Like its counterpart in software testing , white-box wrapping examines the internal processing details of the component and makes code-level modifications to remove any conflict. Gray-box wrapping is applied when the component library provides a component extension language or API that enables conflicts to be removed or masked. Black-box wrapping requires the introduction of pre- and postprocessing at the component interface to remove or mask conflicts. The software team must determine whether the effort required to adequately wrap a component is justified or whether a custom component (designed to eliminate the conflicts encountered) should be engineered instead.
The component composition task assembles qualified, adapted, and engineered components to populate the architecture established for an application. To accomplish this, an infrastructure must be established to bind the components into an operational system. The infrastructure (usually a library of specialized components) provides a model for the coordination of components and specific services that enable components to coordinate with one another and perform common tasks. Among the many mechanisms for creating an effective infrastructure is a set of four “architectural ingredients” that should be present to achieve component composition:
Data exchange model. Mechanisms that enable users and applications to interact and transfer data (e.g., drag and drop, cut and paste) should be defined for all reusable components. The data exchange mechanisms not only allow human-to-software and component-to-component data transfer but also transfer among system resources (e.g., dragging a file to a printer icon for output).
Automation. A variety of tools, macros, and scripts should be implemented to facilitate interaction between reusable components.
Structured storage. Heterogeneous data (e.g., graphical data, voice/video, text, and numerical data) contained in a “compound document” should be organized and accessed as a single data structure, rather than a collection of separate files. “Structured data maintains a descriptive index of nesting structures that applications can freely navigate to locate, create, or edit individual data contents as directed by the end user” .
Underlying object model. The object model ensures that components developed in different programming languages that reside on different platforms can be interoperable. That is, objects must be capable of communicating across a network. To achieve this, the object model defines a standard for component interoperability.