Component Based Development and Advanced OO Design
Mark Collins-Cope

PDF version



1. Introduction

“Components” have been in the news, on and off, for a few years now. Coverage of component related topics has, however, tended to be dominated by discussion of what we call component inter-connection technologies, by which we mean the likes of .NET, J2EE (EJBs) and to some extent CORBA. We believe this focus on inter-connection technologies, whilst important in its own right, misses a bigger picture. In this paper I discuss some of the wider issues related to CBD, and in particular issues of component design.

2. Why components?

To explore of the wider issues surrounding component based development (CBD) it is necessary first to take a step back and ask: why do we want components in the first place?

The (currently unfulfilled) vision of CBD is one of constructing software from pre-defined building blocks, which are “wired together” to create a useful software application.

Inter-connection technologies are clearly important in this: if you can’t get two components to actually communicate at all, it’s obviously unlikely you’re going to be able to build an application from them! Interconnection technologies like .NET enable components written in different programming languages (managed C++, C#, VB.NET, etc.) to communicate – either on a single machine in a distributed machine environment. This - in conjunction with other services such as MTS (Microsoft’s object transaction monitor environment) - provides a development infrastructure that can underpin an enterprise CBD approach. Similarly Sun’s J2EE, although limited to the Java language, provides an alternative component inter-connection environment.

But, coming back to the original question, what is the motivation behind components? If you take a second or two to think about it, it’s apparent the plug and play vision of CBD is primarily intended to reduce the cost and time to market of software development, without compromising on software quality. This is achieved by re-using existing components, which may be either bought from external third parties (of which there are a number now) or developed in-house. So the primary motivation behind components is re-use.

Re-use has been one of the holy grails of software development since I started in working in the software industry some eighteen years ago. Re-use can and does happen (all those applications running under Microsoft Windows re-use a core kernel of code supplied by Microsoft, and standard programming language libraries that have been re-used for years). Methodology and programming language enhancements - such as the wide-spread adoption of the object-oriented software development paradigm – have increased the potential for achieving re-use quite dramatically (polymorphism is particularly important in this).

Component inter-connection technologies are yet another step in the right direction, so why isn’t all software developed by plugging components together?

The answer to this question lies in the answers (or rather the lack of them) to a number of more fundamental questions:

The remainder of this paper discusses the answers to these questions.

3. What is a component?

This may sound like a surprisingly obvious question, but a cursory view of magazine articles, and even some recently published books, shows us that the term “component” is in danger of becoming all things to all men – and consequently completely meaningless. Here’s how Ratio sees it

Firstly, a component is an binary (non-source code) unit of deployment. By unit of deployment I mean it is a constituent part of a larger application – such as a “.class” file in Java, an “assembly” under .NET, a “.dll” file under Windows, or even a “.o” file under Unix. A component is something that would be typically shown as one of the building blocks of an application using deployment diagrams in UML. The emphasis on non-source code is to ensure that components are used in an unmodified fashion. If you change the source of a component you are effectively creating a new component - with all the consequent costs of additional testing, maintenance, duplication (or worse: non-duplication) of bug fixes and so on.

Secondly, a component implements (one or more) well-defined interface(s). This means, purely and simply, that the mechanisms by which the component can be called by its client developers (it’s Application Programming Interface if you like) is clearly defined and hopefully documented. Note that defining a component interface is more than just defining a set of method or procedure calls. It is equally important to document the component’s behaviour (the semantics of its interfaces).

Thirdly, a component provides access to an inter-related set of functionality, in the sense that each of the methods or procedures exposed by the interface(s) are in some way related to each other (otherwise, why are they in the same component?)

Finally, and most likely forgotten, a component may have its behaviour customised in well-defined manners - without access to the source code. This is an important aspect of components if the re-use vision is ever to be achieved. Whilst low-level (technically oriented) infrastructure components such as graph-drawing widgets may be self-contained, any re-usable business (domain) component is likely to require some mechanism by which its behaviour can be modified. Whilst the core functionality of the component will always be the same, different applications may require slightly different functionality (for example if business rules vary across applications).

From the above I hope the following points should be clear:

4. Well designed components

So we’ve decided that a component is a (potentially) re-usable unit of deployment with a well-defined interface, however this, on its own, is not sufficient to guarantee that a component is actually of any use to any one. Components must be designed well if they are to be usable or re-usable.

In many ways, the criteria that define a well-designed component are no different to the criteria that have been used to underpin good modular software design for many years. Components should be highly cohesive internally - they should be implemented by a set of highly collaborative classes – and should be loosely coupled – where possible one component should not rely on another component being there (although in certain circumstances this is unavoidable - in which case one component can be said to be dependent on another).

Examining the design issue more deeply, we can divide the attributes of a well designed component into four major areas:

5. Architecture and re-use

Having discussed some aids to good component design, I’m now going to take a look at the closely related issue of software architecture. Here I’m using the term architecture to mean the structural inter-relationships between the components that make up a system, be they developed in-house or bought from third parties.

5.1. An architectural reference model for CBD (CBD-ARM)

Figure 1 provides a layered architectural reference model [Collins-Cope+2000]which helps us discuss architecture in more detail, and assists in good component design. Note that the layers presented in this model are placeholders for components – not components themselves (and hence the model presented does not preclude dependencies between non-adjacent layers), and that dependencies (between components) are created by either directed association (shown as a line with an simple arrowhead in UML) or implementation of an abstract interface (shown as a line with an open triangle arrowhead in UML).

The layers of the model may be summarised as follows:

A number of simple rules assist the component developer when using this model:

  1. there should be a simple and clear mapping between component structure and source code structure (the simplest being a 1-1 mapping);
  2. there should be a 1 to 1 mapping between component structure and stereotypedpackages in UML (assuming UML is being used during the design process) – we recommend use of the «component subsystem » stereotype;
  3. the level of a component is the highest level of any of its constituent classes;
  4. components should not (and by the above definition, cannot) cross layers;
  5. component dependencies should be either within the same layer or to a lower layer. Even then, dependencies to components within the same layer should be avoided if at all possible;

5.2. Technical versus domain architecture

Considerations of architecture can be broadly separated into two categories: the technical architecture - which is concerned with the underlying platform that needs to be in place to build the application in the first place (does it use Oracle, does it use MQ Series, is it .NET based, is it J2EE based, does it run on Windows, etc.); and the domain architecture – the business domain related components you buy or build to implement business specific functionality.

The CBD-ARM just discussed splits rather neatly along these lines: the technical architecture being made up of components in the platform and infrastructure layers, and the domain architecture being made up of components in either the interface, application or domain layers.

A coherent approach to CBD requires that architectural issues are addressed at both levels. It’s unlikely you’ll be able to re-use two components together if one is based on J2EE and Oracle, and the other is based on .NET and SQL-Server, so a coherent technical architecture is clearly a pre-requisite for any serious component based development to succeed.

5.3. Re-use of business or domain components

Re-use of domain components (those implementing business or domain related functionality, rather than general purpose technical functionality) requires a similar focus on the appropriate layers of the CBD-ARM. It’s interesting to note that the vast majority of commercially available components fall clearly into the “technical” component category – providing general purpose functionality such as graph drawing, XML parsing, and so on.

Re-use of business components, in our experience, most often occurs internally within organisations – if you work for a large company, just ask yourself and how often you and your colleagues re-invent the wheel! The CBD-ARM is specifically intended to encourage this, with its separation of application and domain layers, and has underpinned many of the re-use programmes we have worked on with our clients.

6. Other issues

Although strictly beyond the scope of this paper, its worth mentioning a few other issues that crop up when trying to get CBD really happening:

7. Summary

In this paper I’ve discussed some of the wider issues pertaining to CBD and the closely related topic of advanced OO design. Whilst component inter-connection facilities such as those provided by J2EE and .NET are clearly important, there are many other equally important issues to be considered if the vision of CBD is to be achieved, even partially.

High on the list of additional priorities are having a common understanding of what exactly constitutes a component, having a good understanding of the more advanced principles of OO design that assist in component development, and having a clear understanding of the architectural issues surrounding CBD.

Further information on the issues discussed in this paper can be found in the references that follow (or you can email markcc@ratio.co.uk)

8. References

[Martin-96] Robert C. Martin, “Granularity”, C++ Report, Nov-Dec 1996.
[Martin-97] Robert C. Martin, “Stability”, C++ Report, Feb 1997.
[Collins-Cope+2000] Mark Collins-Cope and Hubert Matthews, “A Reference Architecture for Component Based Development”, OOIS 2000 (proceedings published by Springer). Also available at http://www.ratio.co.uk/techlibrary.html. See also “UML is Upside Down” – Issue 4 of ObjectiveView Magazine.
[Jacobson+94] Ivar Jacobson, Magnus Christerson, Partrik Jonsson, Gunnar Övergaard, “Object Oriented Software Engineering - A Use Case Driven Approach”, Addison-Wesley, 1994.
[Meyer-97] Bertrand Meyer, “Object Oriented Software Engineering (second edition)” - Prentice Hall Professional Technical Reference, Published 1997.
[Martin-96.2] Robert C. Martin, “The Open Closed Principle”, C++ Report, Jan 1996.
[Martin-96.3] Robert C. Martin, “The Interface Segregation Principle”, C++ Report, Aug 1996.