CS 530 - Advanced Software Engineering

Component-Based Software Engineering

Reference: Sommerville, Software Engineering, 10 ed., Chapter 16

 

The big picture

Component-based software engineering (CBSE) is an approach to software development emerged in the 1990's that relies on the reuse of entities called 'software components'. It emerged from the failure of object-oriented development to support effective reuse. Single object classes are too detailed and specific. Components are more abstract than object classes and can be considered to be stand-alone service providers. They can exist as stand-alone entities.

CBSE essentials

Apart from the benefits of reuse, CBSE is based on sound software engineering design principles:

Standards need to be established so that components can communicate with each other and inter-operate. Unfortunately, several competing component standards were established: Sun's Enterprise Java Beans, Microsoft's COM and .NET, CORBA's CCM. In practice, these multiple standards have hindered the uptake of CBSE. It is impossible for components developed using different approaches to work together.

Solution for interoperating standards: component as a service. An executable service is a type of independent component. It has a 'provides' interface but not a 'requires' interface. From the outset, services have been based around standards so there are no problems in communicating between services offered by different vendors. System performance may be slower with services but this approach is replacing CBSE in many systems.

Components and component models

Components provide a service without regard to where the component is executing or its programming language. A component is an independent executable entity that can be made up of one or more executable objects. The component interface is published and all interactions are through the published interface.

Component characteristics:

Composable
For a component to be composable, all external interactions must take place through publicly defined interfaces. In addition, it must provide external access to information about itself, such as its methods and attributes.
Deployable
To be deployable, a component has to be self-contained. It must be able to operate as a stand-alone entity on a component platform that provides an implementation of the component model. This usually means that the component is binary and does not have to be compiled before it is deployed. If a component is implemented as a service, it does not have to be deployed by a user of that component. Rather, it is deployed by the service provider.
Documented
Components have to be fully documented so that potential users can decide whether or not the components meet their needs. The syntax and, ideally, the semantics of all component interfaces should be specified.
Independent
A component should be independent--it should be possible to compose and deploy it without having to use other specific components. In situations where the component needs externally provided services, these should be explicitly set out in a "requires" interface specification.
Standardized
Component standardization means that a component used in a CBSE process has to conform to a standard component model. This model may define component interfaces, component metadata, documentation, composition, and deployment.

The component is an independent, executable entity. It does not have to be compiled before it is used with other components. The services offered by a component are made available through an interface and all component interactions take place through that interface. The component interface is expressed in terms of parameterized operations and its internal state is never exposed.

Component interfaces:

"Provides" interface
Defines the services that are provided by the component to other components. This interface, essentially, is the component API. It defines the methods that can be called by a user of the component.
"Requires" interface
Defines the services that specifies what services must be made available for the component to execute as specified. This does not compromise the independence or deployability of a component because the 'requires' interface does not define how these services should be provided.

Components are accessed using remote procedure calls (RPCs). Each component has a unique identifier (usually a URL) and can be referenced from any networked computer. Therefore it can be called in a similar way as a procedure or method running on a local computer.

A component model is a definition of standards for component implementation, documentation and deployment. Examples of component models: EJB model (Enterprise Java Beans), COM+ model (.NET model), Corba Component Model. The component model specifies how interfaces should be defined and the elements that should be included in an interface definition.

Elements of a component model:

Interfaces
Components are defined by specifying their interfaces. The component model specifies how the interfaces should be defined and the elements, such as operation names, parameters and exceptions, which should be included in the interface definition.
Usage
In order for components to be distributed and accessed remotely, they need to have a unique name or handle associated with them. This has to be globally unique.
Deployment
The component model includes a specification of how components should be packaged for deployment as independent, executable entities.

Component models are the basis for middleware that provides support for executing components. Component model implementations provide: platform services that allow components written according to the model to communicate, and support services that are application-independent services used by different components. To use services provided by a model, components are deployed in a container. This is a set of interfaces used to access the service implementations.

CBSE processes

CBSE processes are software processes that support component-based software engineering. They take into account the possibilities of reuse and the different process activities involved in developing and using reusable components. There are two types of CBSE processes:

CBSE for reuse focuses on component and service development. Components developed for a specific application usually have to be generalised to make them reusable. A component is most likely to be reusable if it associated with a stable domain abstraction (business object). For example, in a hospital stable domain abstractions are associated with the fundamental purpose - nurses, patients, treatments, etc.

Component reusability:

There is a trade-off between reusability and usability. The more general the interface, the greater the reusability but it is then more complex and hence less usable.

To make an existing component reusable:

Existing legacy systems that fulfill a useful business function can be re-packaged as components for reuse. This involves writing a wrapper component that implements provides and requires interfaces then accesses the legacy system. Although costly, this can be much less expensive than rewriting the legacy system.

The development cost of reusable components may be higher than the cost of specific equivalents. This extra reusability enhancement cost should be an organization rather than a project cost. Generic components may be less space-efficient and may have longer execution times than their specific equivalents.

Component management involves deciding how to classify the component so that it can be discovered, making the component available either in a repository or as a service, maintaining information about the use of the component and keeping track of different component versions. A company with a reuse program may carry out some form of component certification before the component is made available for reuse. Certification means that someone apart from the developer checks the quality of the component.

CBSE with reuse process has to find and integrate reusable components. When reusing components, it is essential to make trade-offs between ideal requirements and the services actually provided by available components. This involves:

Component identification issues:

Component validation involves developing a set of test cases for a component (or, possibly, extending test cases supplied with that component) and developing a test harness to run component tests. The major problem with component validation is that the component specification may not be sufficiently detailed to allow you to develop a complete set of component tests. As well as testing that a component for reuse does what you require, you may also have to check that the component does not include any malicious code or functionality that you don't need.

Component composition

Component composition is the process of assembling components to create a system. Composition involves integrating components with each other and with the component infrastructure. Normally you have to write 'glue code' to integrate components.

Three types of component composition:

  1. Sequential composition where the composed components are executed in sequence. This involves composing the provides interfaces of each component.
  2. Hierarchical composition where one component calls on the services of another. The provides interface of one component is composed with the requires interface of another.
  3. Additive composition where the interfaces of two components are put together to create a new component. Provides and requires interfaces of integrated component is a combination of interfaces of constituent components.

When components are developed independently for reuse, their interfaces are often incompatible. Three types of incompatibility can occur:

Adaptor components address the problem of component incompatibility by reconciling the interfaces of the components that are composed. Different types of adaptor are required depending on the type of composition.

When composing components, you may find conflicts between functional and non-functional requirements, and conflicts between the need for rapid delivery and system evolution. You need to make decisions such as: