Chapter 16
Designing with Components and Services
In Chapter 11 we looked at component technology and the concept of the software service. Our concern there was to describe their forms and to consider the properties of components and services that were of importance from the perspective of how they might be modelled.
This chapter looks at how components and services can be composed to create applications, and some factors that we might need to consider when designing with such elements.
16.1Modular design
Chapter 11 addressed the question of how to design components, both in the form of ‘local’ software components, and also software services (which of course, can be viewed as being a form of ‘remote’ component). In this chapter we briefly discuss the question of producing designs for building applications that make use of both components and services.
The two forms have much in common as well as some differences when it comes to producing a design. They particularly share a ‘plug-and-play’ philosophy, arising from the widespread use of dynamic binding when composing an application from existing elements, hence the reference above to the idea of ‘modular’ design. And despite the importance of reuse in software development as a whole, in neither case are there any well-established practices to assist with formulating an overall design model around the concept of reuse. Indeed, up to this point, the ideas about creating software applications presented in Part III have essentially assumed a ‘bespoke’ development process, with the elements making up each application (or product line) largely being different and unique. So, while the development of ideas about component-based software engineering (CBSE) could build upon experiences with using objects, those experiences provided little opportunity for accumulating and formalising declarative and procedural knowledge about modular design.
However, when creating applications from existing components and services, some aspects of incremental design may well be adapted for this purpose, because both forms provide scope for the use of prototyping, particularly exploratory and evolutionary prototyping. Exploratory prototyping allows the designer to investigate the use of different component combinations while developing an application, while evolutionary prototyping may provide an over-arching development context in which the application emerges from a series of intermediate forms.
The use of prototyping rather than the development of more structured design models may however create limited opportunity for providing knowledge transfer that has been derived from experience of composing components. This is because, although components and services are implicitly well-suited to the use of a compositional strategy, the major influence upon design decisions is likely to be the identification of what modules are available from the component catalogue rather than design strategy.
16.2Designing with components
As noted above, there is very little guidance available about how to develop a design by using components. This is true even for a well-established architectural form such as JavaBeans, the component architecture used with the Java platform. The component composition process itself is further complicated by the way that components can be used to perform what we might term horizontal roles within a system (whereby the overall functionality of the application is distributed between them), and also vertical roles in which they provide ‘layers’ of services through component frameworks such as CORBA and. NET. The latter role essentially corresponds to the use of a Layers architectural pattern. This is illustrated in Figure 16.1.

Figure 16.1: Horizontal and vertical integration of components
Our concern here is primarily about how the design choices related to ‘horizontal’ structuring are to be made, on the basis that these provide the detailed design, whereas the ‘vertical’ structuring provides an architectural design. But of course, as always, the two cannot be regarded as entirely separate.
Where the aim is to develop an application by reusing existing components, then in selecting a set of components that can be composed to make up the overall functionality of a system, there are two distinct strategies that might be employed. (These can be viewed as forming extremes of course, and composition may well be undertaken using a mix of these.)
Identify the general needs of the application problem, and search for a set of components that collectively match that functionality, and seek to construct the design (and implicitly, the application) by aggregating these in some way. (This can be termed as an element first strategy.)
Decompose the application problem into well-defined sub-problems that address specific tasks and then seek a set of components that will fit the needs of the individual sub-problems. (This can be termed as a framework first strategy.)
Some small empirical studies that investigated the extent to which either strategy was adopted, and with what level of success, are described in (Pohthong & Budgen 2000) and (Pohthong & Budgen 2001). These used a rather constrained component context (Unix processes), and as might have been expected, for much of the time the participants worked opportunistically, adjusting the choice of strategy as the solution evolved. However, for less experienced designers, the use of an element first strategy did appear to be more likely to result in a working solution. It was thought that this might be partly because identifying the available components might provide better assistance with creating a conceptual model of how the overall application might work.
Reusing existing components with an opportunistic strategy makes it possible to make good use of exploratory prototyping. When the option to develop components rather than simply reuse existing ones is added to this (what we might term a ‘buy or build’ strategy) then the design decisions become even more complex. As indicated in Chapter 11, it is necessary to factor in the knowledge that the cost of developing components for reuse is around four times greater than direct development. Given these issues, we can conclude that simple strategies are unlikely to work for many applications, and that the complexity of component-based design can only really be addressed by an opportunistic strategy.
In composing a system from a set of components, particularly when working opportunistically, a designer needs to be able to model and predict their aggregate behaviour and functionality. In doing this, the designer also needs to identify the potential for the occurrence of any of the issues shown schematically in Figure 16.2. These problems can be classified as follows.

Figure 16.2: Illustrations of some of the problems that might arise in component integration
a) Overlapping functionality. This occurs where two or more components are able to perform a particular application function. The designer's task is to determine which one should perform the task, and how to ensure that only that component performs it. From a design point of view it is definitely undesirable to have the same function performed by different elements (possibly with different limits or ranges), and this also creates a problem for system maintenance and evolution.
b) Missing functionality. The problem arises when the total set of functions provided by the components chosen to make up the application is less than what is needed. The solution is fairly simple, either find another component or (possibly) create one. So this should be a short-term issue with no longer-term technical debt associated with it.
c) Redundant functionality. Components may well provide services over and above those that form the basis for choosing those particular components. This is particularly so for large components. The designer needs to choose between incorporating the added functionality in some way (with possible undesirable consequences) or, preferably, finding some way to exclude the unwanted functions.
d) Architectural mismatch. This issue was discussed in Chapter 11, and arises when there are mismatches between the expectations that each component makes about its context. The study by Yakimovich, Bieman & Basili (1999) provides examples of how architectural mismatch can arise from inconsistencies in:
component packaging—where components may be constructed as linkable elements that need to be integrated into an executable image, or as independent elements, that may be scheduled independently;
type of control—concerning the way that control is organised and transferred between components, and whether this is managed centrally within an application or concurrently (such as through an event-driven mechanism);
type of information flow—whether organised as control flow through method calls, data flow through shared memory, or in a mixed format;
synchronisation between components—referring to whether a component can ‘block’ the execution of other components (synchronous), or can continue to run regardless (asynchronous);
binding time—referring to when the components are attached to connectors, which may occur at compilation, link-editing, run-time etc.
What should be clear from this is that while component-based development offers potential to bring together components from a variety of sources and in a range of forms, it is probably wisest to employ only components that conform to a single architectural style. This doesn't prevent the first three problems arising, but these are likely to be much more tractable than coping with architectural mismatch.
The systematic mapping study by Vale et al. (2016) identified some important gaps in CBSE knowledge, while recognising that some of these were compounded by the diversity of CBSE forms and application areas. Gaps of particular relevance to design included a lack of experience reports about use of CBSE in practice, a lack of clear concepts about CBSE in practice, and a lack of CBSE tool support. CBSE tools do exist but appear to be largely concerned with implementation rather with activities such as modelling.
To complete our discussion of designing with components we look at how components might be used to compose the software needed to support the business of the CCC.
16.3Designing with software services
With any new implementation technology paradigm, there is an inevitable lag between it becoming available and the accumulation of relevant knowledge schema about how to design applications using it. And for more complex forms, such as objects, components and services, there is also a need to establish a consistent context for their use, usually in the form of some sort of framework.
The basic service model, often described as Software as a Service separates possession and ownership of software from its use by employing remote service providers to deliver services ‘on demand’ (Turner et al. 2003, Budgen, Brereton & Turner 2004). It is this paradigm that underpins the concept of the cloud, whereby the user of a service needs to have no detailed knowledge of how it is provided. Indeed, the use of software services depends upon the use of business modelling at least as much as more ‘technological’ design modelling.
Designing for very basic use of the SaaS model then requires little more than using the pattern shown in Figure 15.13, possibly adding an element of orchestration to aid with selecting services.
Beyond that, the lack of clear definitions of what exactly is meant by such terms as Service Oriented Architecture becomes quite a problem. A systematic mapping study performed to identify what exactly was considered to comprise an SOA found that of 921 studies referring to SOA, only 98 provided explicit definitions of what the authors considered this to consist of (Anjum & Budgen 2012). Where definitions did exist, they differed in such aspects as the level of abstraction and the assumed context (consumer, provider, developer).
Integrating the terms that were used to describe SOA in those studies that did provide some form of definition produced a set of characteristics that could be considered to provide a profile of SOA (and which have no particular conflicts or inconsistencies). And hence, these can be considered as factors that need to be considered when designing an application that is to be realised using service forms, and that should ideally be provided by a service framework. (Of course, the application may itself be providing a service.) In brief, these characteristics are as follows.
Architecture. This relates to the overall organisation of an application in terms of the ways that the different services interact. Implicitly, these interactions are usually through SOAP, although REST is also used.
Binding Time. This refers to the time at which a particular service (and hence the service provider) is selected by an application. Some services may be bound when the application is composed, since their use may be intrinsic to its purpose, while others may well be bound dynamically on demand.
Capability. This relates to the purpose of an application or service, viewed from the perspective of the service consumer. The emphasis here lies upon the functional viewpoint, as services are essentially stateless in nature, providing limited scope to use behavioural modelling in any way.
Composition. This relates to the specific configuration of services employed to meet the needs of the end-user (often termed orchestration, particularly in a dynamic context). Composition is effectively a realisation of the design model.
Contracts. Because the use of services is likely to involve third parties as suppliers, it is common for a service provider to offer a Service-Level Agreement that specifies the terms and conditions under which a service will be provided and used. And of course, this may have to be managed dynamically (one of the more challenging aspects of the service model) unless such contracts are negotiated in advance of use.
Delivery. Essentially this is the operational aspect by which a service provides the agreed service functionality.
Distributed Sources. Services can be delivered locally as well as from remote sources, but this aspect is particularly concerned with delivery across a network (implicitly, the web).
Identity. This is essentially the description of a particular service and the ways that it can be accessed.
Interoperability. This relates to the service framework and the way that services can be deployed within this, including the possibility that the end-user has no knowledge about the location or provider of a particular service, and indeed, that such a service may be provided by different sources each time it is requested.
Packaging. A constructional issue concerning the creation of services so as to ensure that a service both provides the required functionality, and also the appropriate interface.
While all of these are factors that influence design of an application in some way, not all of them will necessarily be a direct influence. Characteristics such as packaging and identity are primarily ones that are determined or specified by the service provider, and hence likely to be an indirect influence. Others such as orchestration, binding time and capability are likely to be of much more immediate importance when configuring an application to use services. Figure 16.3 shows how these characteristics map on to the main elements of the service paradigm, by annotating the model provided in Figure 11.5.

Figure 16.3: SOA characteristics mapped on to the service model
Development of SOA applications is apt to employ a complex mix of business and technological modelling. As noted in the last chapter, the use of design patterns has been advocated for more detailed modelling needs (Erl 2009). There has also been some interest in using what are more or less plan-driven forms of approach such as the SOA method (SOAM) proposed in (Offermann & Bub 2009). (There is some discussion of different methods in (Anjum & Budgen 2017).) Modelling would appear to be largely dependent upon the use of UML class and component diagrams.
In many ways, designing SOA applications can be considered as being an indirect form of design. Rather than explicitly determining things like configuration of elements, the SOA designer is more concerned with writing a set of rules for the dynamic orchestration of the services. And these roles are not only concerned with basic service properties, but also with things like Service-Level Agreements that are confirmed or re-negotiated at run time, as well as security.
One question that arises when designing around the use of SOA is the extent to which relevant commercial service provision exists? (A similar issue arises with component-based design, but once a component has been found, its use is less dependent upon the external provider.) As with the use of physical services, adoption of this model does involve an element of risk in that a service provider may cease to trade. Hence employing a service model does implicitly require the availability of multiple providers for a given service. Many of the papers describing and discussing use of services do tend to be focused on quite specific application areas, which may help the emergence of a provider market, possibly related to the use of cloud services.
To complete our discussion of the use of software services in this section, we again turn to the needs of the CCC and consider how this might make use of a service model, including services provided by external providers. For the purposes of this discussion, we assume that some of the more ‘general purpose’ services needed are readily available from external sources.
16.4Empirical knowledge about modular design
The diversity and emerging nature of the technologies covered in this chapter pose something of a challenge for empirical studies. We have already identified the systematic mapping study by Vale et al. (2016) as looking at research activities in CBSE. At time of writing, there is no obvious equivalent study addressing the use of software service technologies.
Key take-home points about designing with components and services
If we view components and software services as being evolutionary stages in modular design of software, we can identify the following lessons about their use.
Design models. Modular design can make use of many of the modelling forms already developed for object-oriented development, possibly augmented by forms such as DFDs where the ‘flow’ nature of service models require such a form.
Design by composition. The emphasis placed upon reuse means that the main design activity is centred upon composition of pre-existing elements. This in turn changes many of the supporting activities, which now involve such tasks as finding modules, negotiating terms of use, and addressing the question of interfacing between modules from different sources.
Business models. One reason for using modular forms is to be able to rapidly assemble software to meet business needs, particularly where these may involve applying application-specific ‘rules’ to the way that fairly standard tasks are performed. So business modelling explicitly plays a much more important role in the use of these technologies than may be the case for other forms.