Chapter 16 · Component-Based Software Engineering
Source review

The original source text, examples, tables and caveats remain available. Source slide numbers and textbook PDF pages are different references. Historical assertions stay attributed to this edition; this page is not a current legal, medical, regulatory or product guide. Classroom activities are labelled separately.

Required selections

Apply one named source concept to the chapter artifact and explain its effect. Finish any uncompleted core topic here; material does not become optional merely because it is reviewed after class. Assignment dates and marks remain in Blackboard.

Original source-slide ledger

Slide 1 · Chapter 16 - Component-based software engineering
Slide 2 · Topics covered
Topics covered
Components and component models 
CBSE processes
Component composition
Slide 3 · Component-based development
Component-based development
Component-based software engineering (CBSE) is an approach to software development 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.
Slide 4 · CBSE essentials
CBSE essentials
Independent components specified by their interfaces.
Component standards to facilitate component integration.
Middleware that provides support for component inter-operability.
A development process that is geared to reuse.
Slide 5 · CBSE and design principles
CBSE and design principles
Apart from the benefits of reuse, CBSE is based on sound software engineering design principles:
Components are independent so do not interfere with each other;
Component implementations are hidden;
Communication is through well-defined interfaces;
One components can be replaced by another if its interface is maintained;
Component infrastructures offer a range of standard services.
Slide 6 · Component standards
Component standards
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.
Slide 7 · Service-oriented software engineering
Service-oriented software engineering
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.
Covered in Chapter 18
Slide 8 · Components and component models
Components and component models
Slide 9 · Components
Components
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;
Slide 10 · Component definitions
Component definitions
Councill and Heinmann:
A software component is a software element that conforms to a component model and can be independently deployed and composed without modification according to a composition standard.
Szyperski:
A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to composition by third-parties.
Slide 11 · Component characteristics
Component characteristics
Slide 12 · Component characteristics
Component characteristics
Slide 13 · Component as a service provider
Component as a service provider
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.
Slide 14 · Component interfaces
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.
Slide 15 · Component interfaces
Component interfaces 
Note UML notation. Ball and sockets can fit together.
Slide 16 · A model of a data collector component
A model of a data collector component
Slide 17 · Component access
Component access
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.
Slide 18 · Component models
Component models
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.
Slide 19 · Basic elements of a component model
Basic elements of a component model
Slide 20 · Elements of a component model
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.
Slide 21 · Middleware support
Middleware support
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;
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.
Slide 22 · Middleware services defined in a component model
Middleware services defined in a component model
Slide 23 · CBSE processes
CBSE processes
Slide 24 · CBSE processes
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. 
Development for reuse 
This process is concerned with developing components or services that will be reused in other applications. It usually involves generalizing existing components.
Development with reuse 
This process is the process of developing new applications using existing components and services.
Slide 25 · CBSE processes
CBSE processes
Slide 26 · Supporting processes
Supporting processes
Component acquisition is the process of acquiring components for reuse or development into a reusable component. 
It may involve accessing locally- developed components or services or finding these components from an external source.
Component management is concerned with managing a company’s reusable components, ensuring that they are properly catalogued, stored and made available for reuse.
Component certification is the process of checking a component and certifying that it meets its specification.
Slide 27 · CBSE for reuse
CBSE for reuse
CBSE for reuse focuses on component 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.
Slide 28 · Component development for reuse
Component development for reuse
Components for reuse may be specially constructed by generalising existing components.
Component reusability
Should reflect stable domain abstractions;
Should hide state representation;
Should be as independent as possible;
Should publish exceptions through the component interface.
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.
Slide 29 · Changes for reusability
Changes for reusability
Remove application-specific methods.
Change names to make them general.
Add methods to broaden coverage.
Make exception handling consistent.
Add a configuration interface for component adaptation.
Integrate required components to reduce dependencies.
Slide 30 · Exception handling
Exception handling
Components should not handle exceptions themselves, because each application will have its own requirements for exception handling. 
Rather, the component should define what exceptions can arise and should publish these as part of the interface.
In practice, however, there are two problems with this:
Publishing all exceptions leads to bloated interfaces that are harder to understand. This may put off potential users of the component.
The operation of the component may depend on local exception handling, and changing this may have serious implications for the functionality of the component.
Slide 31 · Legacy system components
Legacy system components
Existing legacy systems that fulfil 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.
Slide 32 · Reusable components
Reusable components
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.
Slide 33 · Component management
Component management
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.
Slide 34 · CBSE with reuse
CBSE with reuse
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:
Developing outline requirements;
Searching for components then modifying requirements according to available functionality.
Searching again to find if there are better components that meet the revised requirements.
Composing components to create the system.
Slide 35 · CBSE with reuse
CBSE with reuse
Slide 36 · The component identification process
The component identification process
Slide 37 · Component identification issues
Component identification issues
Trust. You need to be able to trust the supplier of a component. At best, an untrusted component may not operate as advertised; at worst, it can breach your security.
Requirements. Different groups of components will satisfy different requirements.
Validation. 
The component specification may not be detailed enough to allow comprehensive tests to be developed.
Components may have unwanted functionality. How can you test this will not interfere with your application?
Slide 38 · Component validation
Component validation 
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.
Slide 39 · Ariane launcher failure – validation failure?
Ariane launcher failure – validation failure?
In 1996, the 1st test flight of the Ariane 5 rocket ended in disaster when the launcher went out of control 37 seconds after take off.
The problem was due to a reused component from a previous version of the launcher (the Inertial Navigation System) that failed because assumptions made when that component was developed did not hold for Ariane 5.
The functionality that failed in this component was not required in Ariane 5.
Slide 40 · Component composition
Component composition
Slide 41 · Component composition
Component composition
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.
Slide 42 · Types of composition
Types of composition
Sequential composition (1) where the composed components are executed in sequence. This involves composing the provides interfaces of each component.
Hierarchical composition (2) where one component calls on the services of another. The provides interface of one component is composed with the requires interface of another.
Additive composition (3) 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.
Slide 43 · Types of component composition
Types of component composition
Slide 44 · Glue code
Glue code
Code that allows components to work together
If A and B are composed sequentially, then glue code has to call A, collect its results then call B using these results, transforming them into the format required by B.
Glue code may be used to resolve interface incompatibilities.
Slide 45 · Interface incompatibility
Interface incompatibility
Parameter incompatibility where operations have the same name but are of different types.
Operation incompatibility where the names of operations in the composed interfaces are different.
Operation incompleteness where the provides interface of one component is a subset of the requires interface of another.
Slide 46 · Components with incompatible interfaces
Components with incompatible interfaces
Slide 47 · Adaptor components
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.
An addressFinder and a mapper component may be composed through an adaptor that strips the postal code from an address and passes this to the mapper component.
Slide 48 · Composition through an adaptor
Composition through an adaptor
The component postCodeStripper is the adaptor that facilitates the sequential composition of addressFinder and mapper components.
Slide 49 · An adaptor linking a data collector and a sensor
An adaptor linking a data collector and a sensor
Slide 50 · Photo library composition
Photo library composition
Slide 51 · Interface semantics
Interface semantics
You have to rely on component documentation to decide if interfaces that are syntactically compatible are actually compatible.
Consider an interface for a PhotoLibrary component:
Slide 52 · Photo Library documentation
Photo Library documentation

“This method adds a photograph to the library and associates the photograph identifier and catalogue descriptor with the photograph.”

 “what happens if the photograph identifier is already associated with a photograph in the library?”

“is the photograph descriptor associated with the catalogue entry as well as the photograph i.e. if I delete the photograph, do I also delete the catalogue information?”
Slide 53 · The Object Constraint Language
The Object Constraint Language
The Object Constraint Language (OCL) has been designed to define constraints that are associated with UML models.
It is based around the notion of pre and post condition specification – common to many formal methods.
Slide 54 · The OCL description of the Photo Library interface
The OCL description of the Photo Library interface 
-- The context keyword names the component to which the conditions apply

context addItem 

-- The preconditions specify what must be true before execution of addItem
pre: PhotoLibrary.libSize() > 0
PhotoLibrary.retrieve(pid) = null

-- The postconditions specify what is true after execution
post:libSize () = libSize()@pre + 1
PhotoLibrary.retrieve(pid) = p 
PhotoLibrary.catEntry(pid) = photodesc

context delete

pre: PhotoLibrary.retrieve(pid) <> null ;

post: PhotoLibrary.retrieve(pid) = null
PhotoLibrary.catEntry(pid) = PhotoLibrary.catEntry(pid)@pre
PhotoLibrary.libSize() = libSize()@pre—1
Slide 55 · Photo library conditions
Photo library conditions
As specified, the OCL associated with the Photo Library component states that:
There must not be a photograph in the library with the same identifier as the photograph to be entered;
The library must exist - assume that creating a library adds a single item to it;
Each new entry increases the size of the library by 1;
If you retrieve using the same identifier then you get back the photo that you added;
If you look up the catalogue using that identifier, then you get back the catalogue entry that you made.
Slide 56 · Composition trade-offs
Composition trade-offs
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:
What composition of components is effective for delivering the functional requirements?
What composition of components allows for future change?
What will be the emergent properties of the composed system?
Slide 57 · Data collection and report generation components
Data collection and report generation components
Slide 58 · Key points
Key points
CBSE is a reuse-based approach to defining and implementing loosely coupled components into systems.
A component is a software unit whose functionality and dependencies are completely defined by its interfaces.
Components may be implemented as executable elements included in a system or as external services.
A component model defines a set of standards that component providers and composers should follow.
The key CBSE processes are CBSE for reuse and CBSE with reuse.
Slide 59 · Key points
Key points
During the CBSE process, the processes of requirements engineering and system design are interleaved.
Component composition is the process of ‘wiring’ components together to create a system.
When composing reusable components, you normally have to write adaptors to reconcile different component interfaces.
When choosing compositions, you have to consider required functionality, non-functional requirements and system evolution.

Select a figure to inspect it at its original size. The original PDF/PPTX retains its full layout and vector diagrams.

Supplied textbook chapter · complete text

The PDF remains authoritative for mathematical layout, figures and tables. Line wrapping and extraction artifacts may occur below; no textbook statement is replaced by a contemporary claim.

PDF page 1 · printed page 464

Inspect the original PDF page

16
Component-based
software engineering



      Objectives

        The objective of this chapter is to describe an approach to software
        reuse based on the composition of standardized, reusable
        components. When you have read this chapter, you will:

       ■ understand what is meant by a software component that may be
           included in a program as an executable element;

       ■ understand the key elements of software component models and
           the support provided by middleware for these models;

       ■ be aware of the key activities in the component-based software
           engineering (CBSE) process for reuse and the CBSE process with
            reuse;

       ■ understand three different types of component composition and
         some of the problems that have to be resolved when components
           are composed to create new components or systems.


     Contents
        16.1 Components and component models
        16.2 CBSE processes
        16.3 Component composition
PDF page 2 · printed page 465

Inspect the original PDF page

                 Chapter 16  ■  Component-based software engineering    465


Component-based software engineering (CBSE) emerged in the late 1990s as an
approach to software systems development based on reusing software components.
Its creation was motivated by frustration that object-oriented development had not
led to extensive reuse, as had been originally suggested. Single-object classes were
too detailed and specific and often had to be bound with an application at compile-
time. You had to have detailed knowledge of the classes to use them, which usually
meant that you had to have the component source code. Selling or distributing
objects as individual reusable components was therefore practically impossible.
  Components are higher-level abstractions than objects and are defined by their
interfaces. They are usually larger than individual objects, and all implementation
details are hidden from other components. Component-based software engineering
is the process of defining, implementing, and integrating or composing these loosely
coupled, independent components into systems.
  CBSE has become as an important software development approach for large-
scale enterprise systems, with demanding performance and security requirements.
Customers are demanding secure and dependable software that is delivered and
deployed more quickly. The only way that these demands can be met is to build soft-
ware by reusing existing components.
  The essentials of component-based software engineering are:

1.  Independent components that are completely specified by their interfaces. There
    should be a clear separation between the component interface and its implemen-
     tation. This means that one implementation of a component can be replaced by
    another, without the need to change other parts of the system.

2.  Component standards that define interfaces and so facilitate the integration of
    components. These standards are embodied in a component model. They define, at
     the very minimum, how component interfaces should be specified and how com-
    ponents communicate. Some models go much further and define interfaces that
    should be implemented by all conformant components. If components conform to
    standards, then their operation is independent of their programming language.
    Components written in different languages can be integrated into the same system.

3.  Middleware that provides software support for component integration. To
   make independent, distributed components work together, you need
    middleware support that handles component communications. Middleware for
    component support handles low-level issues efficiently and allows you to
    focus on application-related problems. In addition, middleware for component
    support may provide support for resource allocation, transaction management,
     security, and concurrency.

4. A development process that is geared to component-based software engineer-
     ing. You need a development process that allows requirements to evolve,
    depending on the functionality of available components.

  Component-based development embodies good software engineering practice. It
often makes sense to design a system using components, even if you have to develop
PDF page 3 · printed page 466

Inspect the original PDF page

466    Chapter 16  ■  Component-based software engineering




           Problems with CBSE

  CBSE is now a mainstream approach to software engineering and is widely used when creating new systems.
   However, when used as an approach to reuse, problems include component trustworthiness, component
    certification, requirements compromises, and prediction of the properties of components, especially when they
   are integrated with other components.

                       http://software-engineering-book.com/web/cbse-problems/


                       rather than reuse these components. Underlying CBSE are sound design principles
                       that support the construction of understandable and maintainable software:

                       1.  Components are independent, so they do not interfere with each other’s opera-
                             tion. Implementation details are hidden. The component’s implementation can
                      be changed without affecting the rest of the system.

                       2.  Components communicate through well-defined interfaces. If these interfaces
                          are maintained, one component can be replaced by another component provid-
                         ing additional or enhanced functionality.

                        3.  Component infrastructures offer a range of standard services that can be used in
                           application systems. This reduces the amount of new code that has to be developed.

                    The initial motivation for CBSE was the need to support both reuse and distributed
                     software engineering. A component was seen as an element of a software system that
                    could be accessed, using a remote procedure call mechanism, by other components run-
                    ning on separate computers. Each system that reused a component had to incorporate its
                own copy of that component. This idea of a component extended the notion of distrib-
                     uted objects, as defined in distributed systems models such as the CORBA specification
                   (Pope 1997). Several different protocols and technology-specific “standards” were
                     introduced to support this view of a component, including Sun’s Enterprise Java Beans
                     (EJB), Microsoft’s COM and .NET, and CORBA’s CCM (Lau and Wang 2007).
                        Unfortunately, the companies involved in proposing standards could not agree on
                    a single standard for components, thereby limiting the impact of this approach to soft-
                  ware reuse. It is impossible for components developed using different approaches to
                 work together. Components that are developed for different platforms, such as .NET
                     or J2EE, cannot interoperate. Furthermore, the standards and protocols proposed
                  were complex and difficult to understand. This was also a barrier to their adoption.
                        In response to these problems, the notion of a component as a service was devel-
                    oped, and standards were proposed to support service-oriented software engineering.
                 The most significant difference between a component as a service and the original
                     notion of a component is that services are stand-alone entities that are external to a
                  program using them. When you build a service-oriented system, you reference the
                      external service rather than including a copy of that service in your system.
                         Service-oriented software engineering is a type of component-based software engi-
                      neering. It uses a simpler notion of a component than that originally proposed in CBSE,
PDF page 4 · printed page 467

Inspect the original PDF page

                                      16.1  ■  Components and component models    467


        where components were executable routines that were included in larger systems. Each
        system that used a component embedded its own version of that component. Service-
         oriented approaches are gradually replacing CBSE with embedded components as an
        approach to systems development. In this chapter, I discuss the use of CBSE with
       embedded components; service-oriented software engineering is covered in Chapter 18.


16.1 Components and component models


       The software reuse community generally agrees that a component is an independent
         software unit that can be composed with other components to create a software system.
       Beyond that, however, people have proposed varying definitions of a software compo-
         nent. Councill and Heineman (Councill and Heineman 2001) define a component as:

        A software element that conforms to a standard component model and can be
           independently deployed and composed without modification according to a
           composition standard.†

           This definition is standards-based so that a software unit that conforms to these stand-
         ards is a component. Szyperski (Szyperski 2002), however, does not mention standards in
          his definition of a component but focuses instead on the key characteristics of components:

        A software component is a unit of composition with contractually-specified
            interfaces and explicit context dependencies only. A software component can
          be deployed independently and is subject to composition by third parties.‡

          Both of these definitions were developed around the idea of a component as an
        element that is embedded in a system, rather than a service that is referenced by the
        system. However, they are equally applicable to service components.
           Szyperski also states that a component has no externally observable state; that is,
        copies of components are indistinguishable. However, some component models,
        such as the Enterprise Java Beans model, allow stateful components, so these do not
        correspond with Szyperski’s definition. While stateless components are certainly
        simpler to use, in some systems stateful components are more convenient and reduce
        system complexity.
         What the above definitions have in common is that they agree that components
         are independent and that they are the fundamental unit of composition in a system. I
         think that, if we combine these proposals, we get a more rounded description of a
         reusable component. Figure 16.1 shows what I consider to be the essential character-
           istics of a component as used in CBSE.


           †Councill, W. T., and G. T. Heineman. 2001. “Definition of a Software Component and Its Elements.”
           In Component-Based Software Engineering, edited by G T Heineman and W T Councill, 5–20. Boston:
         Addison Wesley.
           ‡Szyperski, C. 2002. Component Software: Beyond Object-Oriented Programming, 2nd Ed. Harlow,
        UK: Addison Wesley.
PDF page 5 · printed page 468

Inspect the original PDF page

468    Chapter 16  ■  Component-based software engineering


   Component
    characteristic          Description
    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.


Figure 16.1  Component
characteristics       A useful way of thinking about a component is as a provider of one or more
                         services, even if the component is embedded rather than implemented as a service.
               When a system needs something to be done, it calls on a component to provide that
                      service without caring about where that component is executing or the programming
                   language used to develop the component. For example, a component in a system
                   used in a public library might provide a search service that allows users to search the
                       library catalog. A component that converts from one graphical format to another
                          (e.g., TIFF to JPEG) provides a data conversion service and so on.
                    Viewing a component as a service provider emphasizes two critical characteris-
                         tics of a reusable component:

                       1.  The component is an independent executable entity that is defined by its inter-
                            faces. You don’t need any knowledge of its source code to use it. It can either be
                         referenced as an external service or included directly in a program.

                       2.  The services offered by a component are made available through an interface, and
                                all interactions are through that interface. The component interface is expressed
                            in terms of parameterized operations, and its internal state is never exposed.

                        In principle, all components have two related interfaces, as shown in Figure 16.2.
                  These interfaces reflect the services that the component provides and the services
                       that the component requires to operate correctly:

                        1.  The “provides” interface defines the services provided by the component. This
                            interface is the component API. It defines the methods that can be called by a user
PDF page 6 · printed page 469

Inspect the original PDF page

                                                  16.1  ■  Components and component models    469


                                 Requires interface                         Provides interface
                          Defines the services                                           Defines the services
                             that are needed and            Component                   that are provided
                         should be provided                                        by the component
Figure 16.2  Component   by other components                                             to other components
interfaces

                          of the component. In a UML component diagram, the “provides” interface for a
                      component is indicated by a circle at the end of a line from the component icon.

                        2.  The “requires” interface specifies the services that other components in the system
                      must provide if a component is to operate correctly. If these services are not availa-
                              ble, then the component will not work. This does not compromise the independence
                          or deployability of a component because the “requires” interface does not define
                   how these services should be provided. In the UML, the symbol for a “requires”
                             interface is a semicircle at the end of a line from the component icon. Notice that
                         “provides” and “requires” interface icons can fit together like a ball and socket.

                  To illustrate these interfaces, Figure 16.3 shows a model of a component that has
                   been designed to collect and collate information from an array of sensors. It runs
                   autonomously to collect data over a period of time and, on request, provides collated
                     data to a calling component. The “provides” interface includes methods to add,
                   remove, start, stop, and test sensors. The report method returns the sensor data that
                    has been collected, and the listAll method provides information about the attached
                     sensors. Although I have not shown them here, these methods have associated
                    parameters specifying the sensor identifiers, locations, and so on.
                   The “requires” interface is used to connect the component to the sensors. It
                  assumes that sensors have a data interface, accessed through sensorData, and a man-
                  agement interface, accessed through sensorManagement. This interface has been
                    designed to connect to different types of sensors so that it does not include specific
                     sensor operations such as Test and provideReading. Instead, the commands used by a
                       specific type of sensor are embedded in a string, which is a parameter to the opera-
                       tions in the “requires” interface. Adaptor components parse this parameter string and
                       translate the embedded commands into the specific control interface of each type of
                      sensor. I discuss the use of adaptors later in this chapter, where I show how the data
                       collector component may be connected to a sensor (Figure 16.12).


                                   Requires interface                        Provides interface

                                                                                 addSensor
                                                                                removeSensor                          sensorManagement
                                                                                              startSensor
                                                         Data collector              stopSensor
                                     sensorData                                         testSensor
                                                                                                                    initialize
Figure 16.3  A model
                                                                                              reportof a data collector
component                                                                                                               listAll
PDF page 7 · printed page 470

Inspect the original PDF page

470    Chapter 16  ■  Component-based software engineering




          Components and objects

   Components are often implemented in object-oriented languages, and, in some cases, accessing the “provides”
    interface of a component is done through method calls. However, components and object classes are not the
   same thing. Unlike object classes, components are independently deployable, do not define types, are language-
   independent, and are based on a standard component model.

                   http://software-engineering-book.com/web/components-and-objects/


                    Components are accessed using remote procedure calls (RPCs). Each component
                    has a unique identifier and, using this name, may be called from another computer.
                 The called component uses the same mechanism to access the “required” compo-
                     nents that are defined in its interface.
                An important difference between a component as an external service and a com-
                   ponent as a program element accessed using a remote procedure call is that services
                      are completely independent entities. They do not have an explicit “requires” inter-
                       face. Of course, they do require other components to support their operation, but
                     these are provided internally. Other programs can use services without the need to
                   implement any additional support required by the service.


           16.1.1  Component models

            A component model is a definition of standards for component implementation, doc-
                    umentation, and deployment. These standards are for component developers to
                    ensure that components can interoperate. They are also for providers of component
                    execution infrastructures who provide middleware to support component operation.
                   For service components, the most important component model is the Web Service
                    models, and for embedded components, widely used models include the Enterprise
                    Java Beans (EJB) model and Microsoft’s .NET model (Lau and Wang 2007).
                   The basic elements of an ideal component model are discussed by Weinreich and
                   Sametinger (Weinreich and Sametinger 2001). I summarize these model elements in
                    Figure 16.4. This diagram shows that the elements of a component model define the
                  component interfaces, the information that you need to use the component in a pro-
                   gram, and how a component should be deployed:

                       1.   Interfaces Components are defined by specifying their interfaces. The compo-
                        nent 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. The model should also specify the language used to
                         define the component interfaces.

                      For web services, interface specification uses XML-based languages as
                            discussed in Chapter 18; EJB is Java-specific, so Java is used as the interface
                           definition language; in .NET, interfaces are defined using Microsoft’s Common
PDF page 8 · printed page 471

Inspect the original PDF page

                                                  16.1  ■  Components and component models    471


                                                                 Customization
                                               Naming
                                                      convention

                                     Composition                           Documentation
                                      Interface        Specific      Meta-data     Packaging     Evolution
                                      definition      interfaces        access                     support


                                                          Usage         Deployment                                                 Interfaces
                                                                information        and use
Figure 16.4  Basic
elements of a                                     Component model
component model

                         Intermediate Language (CIL). Some component models require specific inter-
                          faces that must be defined by a component. These are used to compose the com-
                       ponent with the component model infrastructure, which provides standardized
                          services such as security and transaction management.

                       2.  Usage In order for components to be distributed and accessed remotely via
                     RPCs, they need to have a unique name or handle associated with them. This
                        has to be globally unique. For example, in EJB, a hierarchical name is generated
                        with the root based on an Internet domain name. Services have a unique URI
                      (Uniform Resource Identifier).

                    Component meta-data is data about the component itself, such as information
                        about its interfaces and attributes. The meta-data is important because it allows
                         users of the component to find out what services are provided and required.
                    Component model implementations normally include specific ways (such as the
                        use of a reflection interface in Java) to access this component meta-data.

                     Components are generic entities, and, when deployed, they have to be config-
                        ured to fit into an application system. For example, you could configure the
                      Data collector component (Figure 16.3) by defining the maximum number of
                         sensors in a sensor array. The component model may therefore specify how the
                         binary components can be customized for a particular deployment environment.

                       3.  Deployment The component model includes a specification of how components
                       should be packaged for deployment as independent, executable routines.
                      Because components are independent entities, they have to be packaged with all
                         supporting software that is not provided by the component infrastructure, or is
                         not defined in a “requires” interface. Deployment information includes informa-
                           tion about the contents of a package and its binary organization.

                           Inevitably, as new requirements emerge, components will have to be changed or
                          replaced. The component model may therefore include rules governing when
                      and how component replacement is allowed. Finally, the component model may
                         define the component documentation that should be produced. This is used to
                          find the component and to decide whether it is appropriate.
PDF page 9 · printed page 472

Inspect the original PDF page

472    Chapter 16  ■  Component-based software engineering



                                   Support services

                                  Component         Transaction        Resource
                                 management      management    management

                                        Concurrency         Persistence          Security



                                      Platform services

                                                         Interface      Exception      Component
Figure 16.5  Middleware               Addressing   definition   management   communications
services defined in a
component model


                     For components that are executable routines rather than external services, the
                 component model defines the services to be provided by the middleware that
                       supports the executing components. Weinreich and Sametinger use the analogy of an
                     operating system to explain component models. An operating system provides a set
                     of generic services that can be used by applications. A component model implemen-
                       tation provides comparable shared services for components. Figure 16.5 shows some
                     of the services that may be provided by an implementation of a component model.
                   The services provided by a component model implementation fall into two
                     categories:

                       1.  Platform services, which enable components to communicate and interoperate
                           in a distributed environment. These are the fundamental services that must be
                          available in all component-based systems.

                       2.  Support services, which are common services that many different components
                          are likely to require. For example, many components require authentication to
                        ensure that the user of component services is authorized. It makes sense to
                            provide a standard set of middleware services for use by all components. This
                        reduces the costs of component development, and potential component incom-
                              patibilities can be avoided.

                     Middleware implements the common component services and provides interfaces to
                    them. To make use of the services provided by a component model infrastructure, you
                   can think of the components as being deployed in a “container.” A container is an imple-
                    mentation of the support services plus a definition of the interfaces that a component
                  must provide to integrate it with the container. Conceptually, when you add a com
                    ponent to the container, the component can access the support services and the container
                   can access the component interfaces. When in use, the component interfaces themselves
                      are not accessed directly by other components. They are accessed through a container
                       interface that invokes code to access the interface of the embedded component.
                       Containers are large and complex and, when you deploy a component in a con-
                        tainer, you get access to all middleware services. However, simple components may
PDF page 10 · printed page 473

Inspect the original PDF page

                                                           16.2  ■  CBSE processes    473


         not need all of the facilities offered by the supporting middleware. The approach
         taken in web services to common service provision is therefore rather different. For
       web services, standards have been defined for common services such as transaction
       management and security, and these standards have been implemented as program
           libraries. If you are implementing a service component, you only use the common
         services that you need.
         The services associated with a component model have much in common with
         the facilities provided by object-oriented frameworks, which I discussed in
        Chapter 15. Although the services provided may not be as comprehensive, frame-
       work services are often more efficient than container-based services. As a conse-
        quence, some people think that it is best to use frameworks such as SPRING
        (Wheeler and White 2013) for Java development rather than the fully-featured
        component model in EJB.


16.2 CBSE processes


      CBSE processes are software processes that support component-based software
         engineering. They take into account the possibilities of reuse and the different pro-
         cess activities involved in developing and using reusable components. Figure 16.6
        (Kotonya 2003) presents an overview of the processes in CBSE. At the highest level,
         there are two types of CBSE processes:

          1.  Development for reuse This process is concerned with developing components
             or services that will be reused in other applications. It usually involves general-
              izing existing components.

          2.  Development with reuse This process is the process of developing new applica-
              tions using existing components and services.

          These processes have different objectives and therefore include different activi-
            ties. In the development for reuse process, the objective is to produce one or more
         reusable components. You know the components that you will be working with, and
        you have access to their source code to generalize them. In development with reuse,
        you don’t know what components are available, so you need to discover these com-
         ponents and design your system to make the most effective use of them. You may
         not have access to the component source code.
         You can see from Figure 16.6 that the basic processes of CBSE with and for reuse
        have supporting processes that are concerned with component acquisition, compo-
         nent management, and component certification:

          1.  Component acquisition is the process of acquiring components for reuse or devel-
           opment into a reusable component. It may involve accessing locally developed
            components or services or finding these components from an external source.
PDF page 11 · printed page 474

Inspect the original PDF page

474    Chapter 16  ■  Component-based software engineering


                    CBSE processes

                                                                                                                      Specifier,
                                   CBSE for                  CBSE with                Designer,
                                            reuse                          reuse                     Integrator,
                   Domain analyst,                                                            Maintainer
                         Designer,
                       Implementor,                                                                          Librarian,
                                                            Component               Vendor,                         Maintainer,
                                                                                 acquisition               Broker                      Market analyst


                                                                                                              External                              Component           Component                 Librarian                                                                                                   source                                             certification           management

                          Local or
                           external
                                                   Component                                 certifier
                                                                   repository

Figure 16.6  CBSE
processes

                        2.  Component management is concerned with managing a company’s reusable
                       components, ensuring that they are properly catalogued, stored, and made avail-
                          able for reuse.

                        3.  Component certification is the process of checking a component and certifying
                             that it meets its specification.

                    Components maintained by an organization may be stored in a component repos-
                        itory that includes both the components and information about their use.


          16.2.1 CBSE for reuse

              CBSE for reuse is the process of developing reusable components and making them
                      available for reuse through a component management system. The vision of early
                     supporters of CBSE (Szyperski 2002) was that a thriving component marketplace
                  would develop. There would be specialist component providers and component ven-
                     dors who would organize the sale of components from different developers. Software
                     developers would buy components to include in a system or pay for services as they
                  were used. However, this vision has not been realized. There are relatively few com-
                    ponent suppliers, and buying off-the-shelf components is uncommon.
                      Consequently, CBSE for reuse is mostly used within organizations that have
                made a commitment to reuse-driven software engineering. These companies have a
                    base of internally developed components that can be reused. However, these inter-
                      nally developed components may not be reusable without change. They often include
                       application-specific features and interfaces that are unlikely to be required in other
                   programs where the component is reused.
PDF page 12 · printed page 475

Inspect the original PDF page

                                                  16.2  ■  CBSE processes    475


  To make components reusable, you have to adapt and extend the application-
specific components to create more generic and therefore more reusable versions.
Obviously, this adaptation has an associated cost. You have to decide first, whether
a component is likely to be reused and second, whether the cost savings from future
reuse justify the costs of making the component reusable.
  To answer the first of these questions, you have to decide whether or not the com-
ponent implements one or more stable domain abstractions. Stable domain abstrac-
tions are fundamental elements of the application domain that change slowly. For
example, in a banking system, domain abstractions might include accounts, account
holders, and statements. In a hospital management system, domain abstractions might
include patients, treatments, and nurses. These domain abstractions are sometimes
called business objects. If the component is an implementation of a commonly used
domain abstraction or group of related business objects, it can probably be reused.
  To answer the question about cost-effectiveness, you have to assess the costs of
changes that are required to make the component reusable. These costs are the costs of
component documentation and component validation, and of making the component more
generic. Changes that you may make to a component to make it more reusable include:

■ removing application-specific methods;

■ changing names to make them more general;

■ adding methods to provide more complete functional coverage;

■ making exception handling consistent for all methods;

■ adding a “configuration” interface to allow the component to be adapted to
   different situations of use;

■  integrating required components to increase independence.

  The problem of exception handling is a difficult one. In principle, components
should not handle exceptions themselves because each application will have its own
requirements for exception management. Rather, the component should define what
exceptions can arise and should publish these exceptions as part of the interface. For
example, a simple component implementing a stack data structure should detect and
publish stack overflow and stack underflow exceptions. In practice, however, there
are two problems with this process:

1.  Publishing all exceptions leads to bloated interfaces that are harder to under-
     stand. This may put off potential users of the component.

2.  The operation of the component may depend on local exception handling, and
    changing this may have serious implications for the functionality of the component.

  You therefore have to take a pragmatic approach to component exception handling.
Common technical exceptions, where recovery is important for the functioning of the
component, should be handled locally. These exceptions and how they are handled
PDF page 13 · printed page 476

Inspect the original PDF page

476    Chapter 16  ■  Component-based software engineering


                     should be documented with the component. Other exceptions that are related to the busi-
                     ness function of the component should be passed to the calling component for handling.
                        Mili et al. (Mili et al. 2002) discuss ways of estimating the costs of making a compo-
                     nent reusable and the returns from that investment. The benefits of reusing rather than
                     redeveloping a component are not simply productivity gains. There are also quality gains,
                    because a reused component should be more dependable, and time-to-market gains.
                   These are the increased returns that accrue from deploying the software more quickly.
                        Mili et al. present various formulas for estimating these gains, as does the COCOMO
                    model, discussed in Chapter 23. However, the parameters of these formulas are diffi-
                        cult to estimate accurately, and the formulas must be adapted to local circumstances,
                  making them difficult to use. I suspect that few software project managers use these
                   models to estimate the return on investment from component reusability.
                    Whether or not a component is reusable depends on its application domain,
                        functionality, and generality. If the domain is a general one and the component
                   implements standard functionality in that domain, then it is more likely to be reusa-
                        ble. As you add generality to a component, you increase its reusability because it can
                   be applied in a wider range of environments. Unfortunately, this normally means
                       that the component has more operations and is more complex, which makes the
                  component harder to understand and use.
                     There is, therefore, a trade-off between the reusability and understandability of a
                  component. To make a component reusable you have to provide a set of generic
                       interfaces with operations that cater to all of the ways in which the component could
                   be used. Reusability adds complexity and hence reduces component understandabil-
                           ity. This makes it more difficult and time consuming to decide whether a component
                          is suitable for reuse. Because of the time involved in understanding a reusable com-
                    ponent, it is sometimes more cost-effective to reimplement a simpler component
                    with the specific functionality that is required.
              A potential source of components is legacy systems. As I discussed in Chapter 9,
                    legacy systems are systems that fulfill an important business function but are written
                    using obsolete software technologies. As a result, it may be difficult to use them with
                new systems. However, if you convert these old systems to components, their func-
                        tionality can be reused in new applications.
                   Of course, these legacy systems do not normally have clearly defined “requires” and
                     “provides” interfaces. To make these components reusable, you have to create a wrapper
                         that defines the component interfaces. The wrapper hides the complexity of the underly-
                     ing code and provides an interface for external components to access services that are
                      provided. Although this wrapper is a fairly complex piece of software, the cost of wrapper
                    development may be significantly less than the cost of reimplementing the legacy system.
                   Once you have developed and tested a reusable component or service, it then has
                       to be managed for future reuse. 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. If the component is open-source,
                  you may make it available in a public repository such as GitHub or Sourceforge. If it
                          is intended for use in a company, then you may use an internal repository system.
PDF page 14 · printed page 477

Inspect the original PDF page

                                                                       16.2  ■  CBSE processes    477



                                                                                    Modify
                                   Outline
                                                                Identify candidate             requirements                                system
                                                 components            according to discovered                               requirements
                                                                          components




                                                                    Compose
                                    Architectural             Identify candidate                                                                        components to
                                  design              componentsFigure 16.7  CBSE with                                                                   create system
reuse


              A company with a reuse program may carry out some form of component certifi-
                      cation before the component is made available for reuse. Certification means that
                 someone apart from the developer checks the quality of the component. They test the
                  component and certify that it has reached an acceptable quality standard, before it is
                made available for reuse. However, this process can be expensive, and so many
                   companies simply leave testing and quality checking to the component developers.


         16.2.2 CBSE with reuse

                 The successful reuse of components requires a development process tailored to
                     including reusable components in the software being developed. The CBSE with
                     reuse process has to include activities that find and integrate reusable components.
                 The structure of such a process was discussed in Chapter 2, and Figure 16.7 shows
                     the principal activities within that process. Some of these activities, such as the
                              initial discovery of user requirements, are carried out in the same way as in other
                    software processes. However, the essential differences between CBSE with reuse
                  and software processes for original software development are as follows:

                       1.  The user requirements are initially developed in outline rather than in detail, and
                         stakeholders are encouraged to be as flexible as possible in defining their
                         requirements. Requirements that are too specific limit the number of compo-
                         nents that could meet these requirements. However, unlike incremental devel-
                       opment, you need a complete description of the requirements so that you can
                           identify as many components as possible for reuse.

                        2.  Requirements are refined and modified early in the process depending on the
                      components available. If the user requirements cannot be satisfied from available
                       components, you should discuss the related requirements that can be supported
                     by the reusable components. Users may be willing to change their minds if this
                     means cheaper or quicker system delivery.

                        3.  There is a further component search and design refinement activity after the sys-
                     tem architecture has been designed. Apparently, usable components may turn out
PDF page 15 · printed page 478

Inspect the original PDF page

478    Chapter 16  ■  Component-based software engineering



                              Component           Component           ComponentFigure 16.8  The
                                       search                   selection                  validationcomponent
identification process


                            to be unsuitable or may not work properly with other chosen components. You
                   may have to find alternatives to these components. Further requirements changes
                   may therefore be necessary, depending on the functionality of these components.

                       4.  Development is a composition process where the discovered components are
                           integrated. This involves integrating the components with the component model
                           infrastructure and, often, developing adaptors that reconcile the interfaces of
                        incompatible components. Of course, additional functionality may also be
                         required over and above that provided by reused components.

                   The architectural design stage is particularly important. Jacobsen et al. (Jacobsen,
                      Griss, and Jonsson 1997) found that defining a robust architecture is critical for suc-
                      cessful reuse. During the architectural design activity, you may choose a component
                 model and implementation platform. However, many companies have a standard
                   development platform (e.g., .NET), so the component model is predetermined. As I
                     discussed in Chapter 6, you also establish the high-level architecture of the system at
                        this stage and make decisions about system distribution and control.
                An activity that is unique to the CBSE process is identifying candidate compo-
                     nents or services for reuse. This involves a number of subactivities, as shown in
                    Figure 16.8. Initially, your focus should be on search and selection. You need to
                   convince yourself that components are available to meet your requirements.
                    Obviously, you should do some initial checking that the component is suitable, but
                      detailed testing may not be required. In the later stage, after the system architecture
                    has been designed, you should spend more time on component validation. You need
                       to be confident that the identified components are really suited to your application; if
                       not, then you have to repeat the search and selection processes.
                    The first step in identifying components is to look for components that are available
                     within your company or from trusted suppliers. There are few component vendors, so
                  you are most likely to be looking for components that have been developed in your own
                      organization or in the repositories of open-source software that are available. Software
                   development companies can build their own database of reusable components without
                      the risks inherent in using components from external suppliers. Alternatively, you may
                     decide to search code libraries available on the web, such as Sourceforge, GitHub, or
                  Google Code, to see if source code for the component that you need is available.
                    Once the component search process has identified possible components, you have to
                        select candidate components for assessment. In some cases, this will be a straightforward
                         task. Components on the list will directly implement the user requirements, and there will
                     not be competing components that match these requirements. In other cases, however,
                      the selection process is more complex. There will not be a clear mapping of requirements
                     onto components. You may find that several components have to be integrated to meet a
PDF page 16 · printed page 479

Inspect the original PDF page

                                                                       16.2  ■  CBSE processes    479



   The Ariane 5 launcher failure

   While developing the Ariane 5 space launcher, the designers decided to reuse the inertial reference software
   that had performed successfully in the Ariane 4 launcher. The inertial reference software maintains the stability
   of the rocket. The designers decided to reuse this without change (as you would do with components),
   although it included additional functionality that was not required in Ariane 5.
       In the first launch of Ariane 5, the inertial navigation software failed, and the rocket could not be controlled.
   The rocket and its payload were destroyed. The cause of the problem was an unhandled exception when a con-
   version of a fixed-point number to an integer resulted in a numeric overflow. This caused the runtime system to
   shut down the inertial reference system, and launcher stability could not be maintained. The fault had never
   occurred in Ariane 4 because it had less powerful engines and the value that was converted could not be large
   enough for the conversion to overflow.
       This illustrates an important problem with software reuse. Software may be based on assumptions about the
   context where the system will be used, and these assumptions may not be valid in a different situation.
     More information about this failure is available at: http://software-engineering-book.com/case-studies/ariane5/


Figure 16.9  An         specific requirement or group of requirements. You therefore have to decide which of
example of validation   these component compositions provide the best coverage of the requirements.
failure with reused
                   Once you have selected components for possible inclusion in a system, you shouldsoftware
                     then validate them to check that they behave as advertised. The extent of the validation
                      required depends on the source of the components. If you are using a component that
                    has been developed by a known and trusted source, you may decide that component
                        testing is unnecessary. You simply test the component when it is integrated with other
                    components. On the other hand, if you are using a component from an unknown source,
                  you should always check and test that component before including it in your system.
                   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. Components are usually specified infor-
                     mally, with the only formal documentation being their interface specification. This
               may not include enough information for you to develop a complete set of tests that
                  would convince you that the component’s advertised interface is what you require.
                  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 malicious code or functionality
                       that you don’t need. Professional developers rarely use components from untrusted
                      sources, especially if these sources do not provide source code. Therefore, the mali-
                     cious code problem does not usually arise. However, reused components may often
                     contain functionality that you don’t need, and you have to check that this functional-
                         ity will not interfere with your use of the component.
                   The problem with unnecessary functionality is that it may be activated by the
                  component itself. While this may have no effect on the application reusing the com-
                     ponent, it can slow down the component, cause it to produce surprising results or, in
                     exceptional cases, cause serious system failures. Figure 16.9 summarizes a situation
                  where the failure of a reused software system, which had unnecessary functionality,
                      led to catastrophic system failure.
PDF page 17 · printed page 480

Inspect the original PDF page

480    Chapter 16  ■  Component-based software engineering


                   The problem in the Ariane 5 launcher arose because the assumptions made about
                      the software for Ariane 4 were invalid for Ariane 5. This is a general problem with
                     reusable components. They are originally implemented for a specific application
                   environment and, naturally, embed assumptions about that environment. These
                    assumptions are rarely documented, so when the component is reused, it is impossi-
                      ble to develop tests to check if the assumptions are still valid. If you are reusing a
                  component in a new environment, you may not discover the embedded environmen-
                          tal assumptions until you use the component in an operational system.


        16.3 Component composition


                 Component composition is the process of integrating components with each other,
                  and with specially written “glue code” to create a system or another component. You
                   can compose components in several different ways, as shown in Figure 16.10. From
                          left to right these diagrams illustrate sequential composition, hierarchical composi-
                        tion, and additive composition. In the discussion below, I assume that you are com-
                    posing two components (A and B) to create a new component:

                       1.  Sequential composition In a sequential composition, you create a new compo-
                        nent from two existing components by calling the existing components in
                        sequence. You can think of the composition as a composition of the “provides
                           interfaces.” That is, the services offered by component A are called, and the
                            results returned by A are then used in the call to the services offered by compo-
                         nent B. The components do not call each other in sequential composition but are
                           called by the external application. This type of composition may be used with
                     embedded or service components.

                   Some extra glue code may be required to call the component services in the right
                         order and to ensure that the results delivered by component A are compatible
                        with the inputs expected by component B. The “glue code” transforms these
                         outputs to be of the form expected by component B.

                        2.   Hierarchical composition This type of composition occurs when one component
                              calls directly on the services provided by another component. That is, component
               A calls component B. The called component provides the services that are required
                     by the calling component. Therefore, the “provides” interface of the called com-
                        ponent must be compatible with the “requires” interface of the calling component.

                    Component A calls on component B directly, and, if their interfaces match,
                          there may be no need for additional code. However, if there is a mismatch
                      between the “requires” interface of A and the “provides” interface of B, then
                    some conversion code may be required. As services do not have a “requires”
                            interface, this mode of composition is not used when components are imple-
                      mented as services accessed over the web.
PDF page 18 · printed page 481

Inspect the original PDF page

                                                              16.3  ■  Component composition    481




                              A               A


                                                              A          B



                             B              B

Figure 16.10  Types of
component composition               (1)                   (2)                        (3)



                        3.   Additive composition This occurs when two or more components are put together
                         (added) to create a new component, which combines their functionality. The “pro-
                         vides” interface and “requires” interface of the new component are a combination
                         of the corresponding interfaces in components A and B. The components are
                           called separately through the external interface of the composed component and
                   may be called in any order. A and B are not dependent and do not call each other.
                        This type of composition may be used with embedded or service components.

                 You might use all the forms of component composition when creating a system.
                     In all cases, you may have to write “glue code” that links the components. For exam-
                        ple, for sequential composition, the output of component A typically becomes the
                     input to component B. You need intermediate statements that call component A,
                       collect the result, and then call component B, with that result as a parameter. When
                  one component calls another, you may need to introduce an intermediate component
                       that ensures that the “provides” interface and the “requires” interface are compatible.
                 When you write new components especially for composition, you should design the
                       interfaces of these components so that they are compatible with other components in
                     the system. You can therefore easily compose these components into a single unit.
                  However, when components are developed independently for reuse, you will often be
                     faced with interface incompatibilities. This means that the interfaces of the components
                        that you wish to compose are not the same. Three types of incompatibility can occur:

                        1.  Parameter incompatibility The operations on each side of the interface have the
                     same name, but their parameter types or the number of parameters are different. In
                         Figure 16.11, the location parameter returned by addressFinder is incompatible
                         with the parameters required by the displayMap and printMap methods in mapDB.

                       2.  Operation incompatibility The names of the operations in the provides and
                          “requires” interfaces are different. This is a further incompatibility between the
                      components shown in Figure 16.11.

                       3.  Operation incompleteness The “provides” interface of a component is a subset
                         of the “requires” interface of another component, or vice versa.
PDF page 19 · printed page 482

Inspect the original PDF page

482    Chapter 16  ■  Component-based software engineering


                                                                                            string location (string pn)
                    phoneDatabase (string command)
                                                                                             string owner (string pn)
                                                           addressFinder
                                                                                             string propertyType (string pn)



                                                                        displayMap (string postCode, scale)
                      mapDB (string command)

                                                   mapper       printMap (string postCode, scale)
Figure 16.11 
Components with
incompatible interfaces

                        In all cases, you tackle the problem of incompatibility by writing an adaptor that
                      reconciles the interfaces of the two components being reused. An adaptor compo-
                    nent converts one interface to another.
                    The precise form of the adaptor depends on the type of composition. Sometimes, as
                       in the next example, the adaptor takes a result from one component and converts it into
                    a form where it can be used as an input to another. In other cases, the adaptor may be
                       called by component A as a proxy for component B. This situation occurs if A wishes
                       to call B, but the details of the “requires” interface of A do not match the details of the
                     “provides” interface of B. The adaptor reconciles these differences by converting its
                      input parameters from A into the required input parameters for B. It then calls B to
                       deliver the services required by A.
                  To illustrate adaptors, consider the two simple components shown in Figure 16.11,
                 whose interfaces are incompatible. These might be part of a system used by the emer-
                   gency services. When the emergency operator takes a call, the phone number is input
                       to the addressFinder component to locate the address. Then, using the mapper compo-
                       nent, the operator prints a map to be sent to the vehicle dispatched to the emergency.
                   The first component, addressFinder, finds the address that matches a phone num-
                       ber. It can also return the owner of the property associated with the phone number and
                      the type of property. The mapper component takes a post code (in the United States,
                    a standard ZIP code with the additional four digits identifying property location) and
                      displays or prints a street map of the area around that code at a specified scale.
                     These components are composable in principle because the property location
                     includes the post or ZIP code. However, you have to write an adaptor component
                       called postCodeStripper that takes the location data from addressFinder and strips out
                      the post code. This post code is then used as an input to mapper, and the street map is
                     displayed at a scale of 1:10,000. The following code, which is an example of sequential
                     composition, illustrates the sequence of calls that is required to implement this process:

                       address = addressFinder.location (phonenumber) ;
                     postCode = postCodeStripper.getPostCode (address) ;
                      mapper.displayMap(postCode, 10000) ;

                      Another case in which an adaptor component may be used is in hierarchical composi-
                         tion, where one component wishes to make use of another but there is an incompatibility
PDF page 20 · printed page 483

Inspect the original PDF page

                                                              16.3  ■  Component composition    483



                                        sensorManagement                             addSensor
                                          start                                                                                       removeSensor
                                                                                                      startSensor                                  stop                         sensor          Adaptor                                                                Data collector              stopSensor
                                                                                                    testSensor                                                   sensorData
                                 getdata                                                                           initializeFigure 16.12  An
                                                                                                      reportadaptor linking a data
collector and a sensor                                                                                                            listAll


                   between the “provides” interface and “requires” interface of the components in the
                     composition. I have illustrated the use of an adaptor in Figure 16.12 where an adaptor
                           is used to link a data collector and a sensor component. These could be used in the
                    implementation of a wilderness weather station system, as discussed in Chapter 7.
                   The sensor and data collector components are composed using an adaptor that
                      reconciles the “requires” interface of the data collection component with the “pro-
                     vides” interface of the sensor component. The data collector component has been
                    designed with a generic “requires” interface that supports sensor data collection and
                     sensor management. For each of these operations, the parameter is a text string rep-
                      resenting the specific sensor commands. For example, to issue a collect command,
                  you would say sensorData(“collect”). As I have shown in Figure 16.12, the sensor
                          itself has separate operations such as start, stop, and getdata.
                    The adaptor parses the input string, identifies the command (e.g., collect), and then calls
                     Sensor.getdata to collect the sensor value. It then returns the result (as a character string)
                       to the data collector component. This interface style means that the data collector can interact
                     with different types of sensor. A separate adaptor, which converts the sensor commands
                   from Data collector to the sensor interface, is implemented for each type of sensor.
                   The above discussion of component composition assumes you can tell from the
                  component documentation whether or not interfaces are compatible. Of course, the
                       interface definition includes the operation name and parameter types, so you can make
                 some assessment of the compatibility from this. However, you depend on the compo-
                     nent documentation to decide whether the interfaces are semantically compatible.
                  To illustrate this problem, consider the composition shown in Figure 16.13. These
                   components are used to implement a system that downloads images from a camera and
                       stores them in a photograph library. The system user can provide additional information
                       to describe and catalog the photograph. To avoid clutter, I have not shown all interface


                                                                        getImage                                          addItem                                                                               Image
                                                              adaptor                                                                              Manager
                                Photo      retrieve
                                        Library
                                                  catEntry                                                                       getCatalogEntry

                                                             User
Figure 16.13  Photo                                               Interface
library composition
PDF page 21 · printed page 484

Inspect the original PDF page

484    Chapter 16  ■  Component-based software engineering



     — The context keyword names the component to which the conditions apply

     context addItem

     — The preconditions specify what must be true before execution of addItem
     pre:      PhotoLibrary.libSize() > 0
                  PhotoLibrary.retrieve(pid) = null

     — The postconditions specify what is true after execution
     post:    libSize () = libSize()@pre + 1
               PhotoLibrary.retrieve(pid) = p
               PhotoLibrary.catEntry(pid) = photodesc

     context delete

     pre:      PhotoLibrary.retrieve(pid) <> null ;

     post:    PhotoLibrary.retrieve(pid) = null
               PhotoLibrary.catEntry(pid) = PhotoLibrary.catEntry(pid)@pre
               PhotoLibrary.libSize() = libSize()@pre—1



Figure 16.14  The
OCL description of     methods here. Rather, I simply show the methods that are needed to illustrate the com-
the Photo Library      ponent documentation problem. The methods in the interface of Photo Library are:
interface
                         public void addItem (Identifier pid ; Photograph p; CatalogEntry photodesc) ;
                         public Photograph retrieve (Identifier pid) ;
                         public CatalogEntry catEntry (Identifier pid) ;

                   Assume that the documentation for the addItem method in Photo Library is:

                       This method adds a photograph to the library and associates the photograph
                           identifier and catalog descriptor with the photograph.

                      This description appears to explain what the component does, but consider the
                    following questions:

                 ■ What happens if the photograph identifier is already associated with a photograph
                          in the library?

                 ■  Is the photograph descriptor associated with the catalog entry as well as the
                        photograph? That is, if you delete the photograph, do you also delete the catalog
                       information?

                     There is not enough information in the informal description of addItem to answer
                     these questions. Of course, it is possible to add more information to the natural lan-
                  guage description of the method, but in general, the best way to resolve ambiguities
                          is to use a formal language to describe the interface. The specification shown in
                    Figure 16.14 is part of the description of the interface of Photo Library that adds
                    information to the informal description.
PDF page 22 · printed page 485

Inspect the original PDF page

                                         16.3  ■  Component composition    485


   Figure 16.14 shows pre- and postconditions that are defined in a notation based on
the object constraint language (OCL), which is part of the UML (Warmer and Kleppe
2003). OCL is designed to describe constraints in UML object models; it allows you
to express predicates that must always be true, that must be true before a method has
executed; and that must be true after a method has executed. These are invariants,
preconditions, and postconditions. To access the value of a variable before an opera-
tion, you add @pre after its name. Therefore, using age as an example:

   age = age@pre + 1

   This statement means that the value of age after an operation is one more than it
was before that operation.
  OCL-based approaches are primarily used in model-based software engineering
to add semantic information to UML models. The OCL descriptions may be used to
drive code generators in model-driven engineering. The general approach has been
derived from Meyer’s Design by Contract approach (Meyer 1992), in which the
interfaces and obligations of communicating objects are formally specified and
enforced by the runtime system. Meyer suggests that using Design by Contract is
essential if we are to develop trusted components (Meyer 2003).
   Figure 16.14 shows the specification for the addItem and delete methods in Photo
Library. The method being specified is indicated by the keyword context and the pre- and
postconditions by the keywords pre and post. The preconditions for addItem state that:

1.  There must not be a photograph in the library with the same identifier as the
    photograph to be entered.

2.  The library must exist—assume that creating a library adds a single item to it so
     that the size of a library is always greater than zero.

3.  The postconditions for addItem state that:

   The size of the library has increased by 1 (so only a single entry has been made).

     If you retrieve using the same identifier, then you get back the photograph that
    you added.

     If you look up the catalog using that identifier, you get back the catalog entry
     that you made.

  The specification of delete provides further information. The precondition states
that to delete an item, it must be in the library, and, after deletion, the photo can no
longer be retrieved and the size of the library is reduced by 1. However, delete does
not delete the catalog entry—you can still retrieve it after the photo has been deleted.
The reason for this is that you may wish to maintain information in the catalog about
why a photo was deleted, its new location, and so on.
  When you create a system by composing components, you may find that there
are potential conflicts between functional and non-functional requirements, the
need to deliver a system as quickly as possible, and the need to create a system that
PDF page 23 · printed page 486

Inspect the original PDF page

486    Chapter 16  ■  Component-based software engineering


                                (a)        Data                  Data                Report
                                          collection           management           generator                                                                                              Report



Figure 16.15  Data                         Data
                               (b)                                      Databasecollection and report                                                collection
generation components                                                               Report

                   can evolve as requirements change. You may have to take trade-offs into account
                      for component decisions:

                       1.  What composition of components is most effective for delivering the functional
                        requirements for the system?

                       2.  What composition of the components will make it easier to adapt the composite
                     component when its requirements change?

                       3.  What will be the emergent properties of the composed system? These properties
                         include performance and dependability. You can only assess these properties
                      once the complete system is implemented.

                        Unfortunately, in many situations the solutions to the composition problems may
                        conflict. For example, consider a situation such as that illustrated in Figure 16.15,
                  where a system can be created through two alternative compositions. The system is
                    a data collection and reporting system where data is collected from different sources,
                     stored in a database, and then different reports summarizing that data are produced.
                      Here, there is a potential conflict between adaptability and performance.
                   Composition (a) is more adaptable, but composition (b) is likely to be faster and more
                         reliable. The advantages of composition (a) are that reporting and data management
                     are separate, so there is more flexibility for future change. The data management
                   system could be replaced, and, if reports are required that the current reporting com-
                   ponent cannot produce, that component can also be replaced without having to
                   change the data management component.
                        In composition (b), a database component with built-in reporting facilities (e.g.,
                     Microsoft Access) is used. The key advantage of composition (b) is that there are fewer
                   components, so this will be a faster implementation because there are no component
                   communication overheads. Furthermore, data integrity rules that apply to the database
                       will also apply to reports. These reports will not be able to combine data in incorrect
                   ways. In composition (a), there are no such constraints, so errors in reports could occur.
                        In general, a good composition principle to follow is the principle of separation of
                     concerns. That is, you should try to design your system so that each component has
                    a clearly defined role. Ideally, component roles should not overlap. However, it may
                   be cheaper to buy one multifunctional component rather than two or three separate
                   components. Furthermore, dependability or performance penalties may be incurred
                when multiple components are used.
PDF page 24 · printed page 487

Inspect the original PDF page

                                                              16.3 Chapter■  Component16  ■  Furthercomposition reading     487487

 Key Points


   ■  Component-based software engineering is a reuse-based approach to defining, implementing,
       and composing loosely coupled independent components into systems.

   ■  A component is a software unit whose functionality and dependencies are completely defined
       by a set of public interfaces. Components can be composed with other components without
       knowledge of their implementation and can be deployed as an executable unit.

   ■  Components may be implemented as executable routines that are included in a system or as
        external services that are referenced from within a system.

   ■  A component model defines a set of standards for components, including interface standards,
       usage standards, and deployment standards. The implementation of the component model pro-
        vides a set of common services that may be used by all components.

   ■  During the CBSE process, you have to interleave the processes of requirements engineering and
       system design. You have to trade off desirable requirements against the services that are avail-
        able from existing reusable components.

   ■  Component composition is the process of “wiring” components together to create a system.
       Types of composition include sequential composition, hierarchical composition, and additive
        composition.

   ■  When composing reusable components that have not been written for your application, you may
       need to write adaptors or “glue code” to reconcile the different component interfaces.

   ■  When choosing compositions, you have to consider the required functionality of the system, the
        non-functional requirements, and the ease with which one component can be replaced when the
       system is changed.



Further  Re ading

   Component Software: Beyond Object-Oriented Programming, 2nd ed. This updated edition of the
      first book on CBSE covers technical and nontechnical issues in CBSE. It has more detail on specific
    technologies than Heineman and Councill’s book and includes a thorough discussion of market
     issues. (C. Szyperski, Addison-Wesley, 2002).

     “Specification, Implementation and Deployment of Components.” A good introduction to the funda-
    mentals of CBSE. The same issue of the CACM includes articles on components and component-
    based development. (I. Crnkovic, B. Hnich, T. Jonsson, and Z. Kiziltan, Comm. ACM, 45(10), October
    2002) http://dx.doi.org/10.1145/570907.570928

    “Software Component Models.” This comprehensive discussion of commercial and research compo-
    nent models classifies these models and explains the differences between them. (K-K. Lau and Z.
    Wang, IEEE Transactions on Software Engineering, 33 (10), October 2007) http://dx.doi.
    org/10.1109/TSE.2007.70726
PDF page 25 · printed page 488

Inspect the original PDF page

488 488     ChapterChapter 16 16  ■ ■  Component-basedComponent-based softwaresoftware engineeringengineering



    “Software Components Beyond Programming: From Routines to Services.” This is the opening arti-
     cle in a special issue of the magazine that includes several articles on software components. This
     article discusses the evolution of components and how service-oriented components are replacing
    executable program routines. (I. Crnkovic, J. Stafford, and C. Szyperski, IEEE Software, 28 (3), May/
    June 2011) http://dx.doi.org/10.1109/MS.2011.62

    Object Constraint Language (OCL) Tutorial. A good introduction to the use of the object-constraint
    language. (J. Cabot, 2012) http://modeling-languages.com/ocl-tutorial/



Website

    PowerPoint slides for this chapter:

    www.pearsonglobaleditions.com/Sommerville

    Links to supporting videos:

    http://software-engineering-book.com/videos/software-reuse/

   A more detailed discussion of the Ariane5 accident:

    http://software-engineering-book.com/case-studies/ariane5/



Exercises

    16.1. What are the design principles underlying the CBSE that support the construction of under-
         standable and maintainable software?

    16.2. The principle of component independence means that it ought to be possible to replace one
        component with another that is implemented in a completely different way. Using an example,
          explain how such component replacement could have undesired consequences and may lead
          to system failure.

    16.3. In a reusable component, what are the critical characteristics that are emphasized when the
        component is viewed as a service?

    16.4. Why is it important that components should be based on a standard component model?

    16.5. Using an example of a component that implements an abstract data type such as a stack or a
              list, show why it is usually necessary to extend and adapt components for reuse.

     16.6. What are the essential differences between CBSE with reuse and software processes for original
          software development?

    16.7. Design the “provides” interface and the “requires” interface of a reusable component that
        may be used to represent a patient in the Mentcare system that I introduced in Chapter 1.
PDF page 26 · printed page 489

Inspect the original PDF page

                                                              16.3  ■ ChapterComponent16  ■ composition References     489489



          16.8. Using examples, illustrate the different types of adaptor needed to support sequential com-
            position, hierarchical composition, and additive composition.

          16.9. Design the interfaces of components that might be used in a system for an emergency con-
             trol room. You should design interfaces for a call-logging component that records calls
         made, and a vehicle discovery component that, given a post code (zip code) and an incident
            type, finds the nearest suitable vehicle to be dispatched to the incident.

    16.10.  It has been suggested that an independent certification authority should be established. Vendors
          would submit their components to this authority, which would validate that the component was
            trustworthy. What would be the advantages and disadvantages of such a certification authority?



References

     Councill, W. T., and G. T. Heineman. 2001. “Definition of a Software Component and Its Elements.”
     In Component-Based Software Engineering, edited by G. T. Heineman and W. T. Councill, 5–20.
     Boston: Addison-Wesley.

    Jacobsen, I., M. Griss, and P. Jonsson. 1997. Software Reuse. Reading, MA: Addison-Wesley.

    Kotonya, G. 2003. “The CBSE Process: Issues and Future Visions.” In 2nd CBSEnet Workshop. Budapest,
    Hungary. http://miro.sztaki.hu/projects/cbsenet/budapest/presentations/Gerald-CBSEProcess.ppt

    Lau, K-K., and Z. Wang. 2007. “Software Component Models.” IEEE Trans. on Software Eng. 33 (10):
    709–724. doi:10.1109/TSE.2007.70726.

    Meyer, B. 1992. “Applying Design by Contract.” IEEE Computer 25 (10): 40–51. doi:10.1109/2.161279.

                     . 2003. “The Grand Challenge of Trusted Components.” In Proc. 25th Int. Conf. on Software
    Engineering. Portland, OR: IEEE Press. doi:10.1109/ICSE.2003.1201252.

     Mili, H., A. Mili, S. Yacoub, and E. Addy. 2002. Reuse-Based Software Engineering. New York: John
    Wiley & Sons.

    Pope, A. 1997. The CORBA Reference Guide: Understanding the Common Object Request Broker
     Architecture. Harlow, UK: Addison-Wesley.

    Szyperski, C. 2002. Component Software: Beyond Object-Oriented Programming, 2nd ed. Harlow,
    UK: Addison-Wesley.

    Warmer, J., and A. Kleppe. 2003. The Object Constraint Language: Getting Your Models Ready for
   MDA. Boston: Addison-Wesley.

    Weinreich, R., and J. Sametinger. 2001. “Component Models and Component Services: Concepts and
     Principles.” In Component-Based Software Engineering, edited by G. T. Heineman and W. T. Councill,
    33–48. Boston: Addison-Wesley.

    Wheeler, W., and J. White. 2013. Spring in Practice. Greenwich, CT: Manning Publications.