Computer Programming/Component based software development
BEng Software Engineering
- 1 Component Oriented Programming
- 1.1 The Software Crisis
- 1.2 Characterization of Components
- 1.3 Component Models
- 1.4 Impacts of CBSD
- 1.5 Differences to Object Oriented Programming
- 1.6 Composition Patterns and Software Architecture
- 1.7 The JavaBeans Component Model
Component Oriented Programming
Software components is at the moment one of the most popular buzz words in the software engineering community. This chapter surveys component technology, its reuse concepts and characteristics. Then, we will give a short overview of software architecture and its relation to component based development. Finally, we will examine JavaBeans as an example of a component model.
The Software Crisis
In the year 1968 on a NATO conference in Garmisch Partenkirchen for the first time the "software crisis" was mentioned. It was admitted that software development is difficult, even so difficult that it has to be considered as an own engineering discipline. Also, the hope aroused that a way out from the misery could be the formation of a new software component industry and component market.
The state of software development was compared to that of many industries in the early 19th century: the products were hand-crafted, expensive, and error prone. A characteristic of maturing industries is that it fabricates products that are assembled of many small standardized and exchangeable parts.
An example is electronic engineering, where small electronic components like diodes, resistors and transistors are not designed for a single application but for numerous and different ones. They can be composed on circuit boards to larger integrated circuits (IC). A single part can simply be replaced by others, provided that it offers the same functionality. Standards like the ISO, ANSI, or DIN guarantee that components are compatible and interchangeable.
Characterization of Components
Software development tries to imitate these reuse mechanisms. The idea is to develop software systems by assembling a set of independently developed components off-the-shelf (COTS) in a 'plug and play' manner.
The notion of a "software component" is already quite old, but in recent time it has changed considerably. While in the early days of programming, software components were mostly seen as source code modules like FORTRAN libraries, one has nowadays more requirements to components. There is no common definition of what a software component actually is. The problems are that the point of view depends much on the background of the author, and that there was in the last years so much discussion about components, that the notion of a component became somewhat fuzzy and ambiguous.
Yet, there are a couple of generic properties, one usually associates with software components. A good starting point is a definition made at the ECOOP 96 conference:
'"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."Clemens Szyperski, Component Software, ACM Press/Addison-Wesley, England, (1998).
Next, we will describe the unfamiliar terms occurring in the definition in more detail.
Probably the most important characteristic is that components completely hide their implementation. The importance was stressed already very early by Parnas' information hiding principle:
"Every module hides an important design decision as well as its implementation behind a well-defined interface which does not change when the design decision or the implementation changes"
Components are like black boxes: The programmer knows, how the outside looks like, and what the component can provide, but he does not know how it works internally. At a first glance, this total encapsulation might seem like a limitation, but we will see that it actually is a help.
The application builder profits insofar as he can replace the component by another one, if it supports the same interface and functionality. In addition, he needs not understand the inner working, but only the interface of the component.
The component provider, on the other hand, can change the implementation of the component as long as the interface is still satisfied. The interface is a quite important term in CBSD. It is defined by "a named collection of methods representing one functionality". An interface serves as a kind of contract between component provider and component user. It should not only mention the services of a component but also its dependencies to its environment.
The absence of source code imposes some difficulties that need to be solved. First, it must still be possible to adjust a component to the individual requirements of a user. Adaptation without knowledge about the components implementation is called customization. Further, components must offer a mechanism to get information about the their specification. This self-descriptiveness is achieved by introspection.
Components are easily transferable into different application contexts. As a consequence, components need to be self-contained software elements, independent from any other components. The independence is so strict that even implementation inheritance is forbidden, because it makes a component dependent from its superclass, and changing the superclass can break the component. Interface inheritance, which is a mere subsumption of feature specifications, is allowed.
So that components are exchangeable, components may ideally not address one another directly, but through an indirection mechanism. A central registry stores all information about the components and interfaces. Each time, a client wants to invoke a method, it queries the registry for the required interface, which, in turn returns a reference to the implementing component.
The next demand one makes to components is that they are interoperable, that means they must have the capacity to communicate with components programmed in another programming language or located on a different host. In addition, they must be themselves transferable to other operating systems and hardware platforms. These requirements are ensured by virtual machines, cross-compilers and middleware like Avaki EII from Sybase, CORBA from OMG and DCOM from Microsoft.
Components are not used in isolation, but according to a software architecture that determines the interfaces that components may have and how components can be composed. A component model provides a common framework in which components interact. Component models are programming guidelines that have to be followed so that the component can be used. Outside of the framework, the component is not usable. Two important component models are JavaBeans from Sun Microsystems and ActiveX from Microsoft, which is based on the Component Object Model (COM). CSBD owes its attention and success mainly to these two component models. However, no existing component model realizes all features that are expected of components.
Impacts of CBSD
If one day CBSD really gets established in a large scale, it will bring fundamental changes in the way software is developed. Through Component Based Development, the process of programming components gets separated from that of composing components to applications. The hope is that components can be plugged together as easily as Lego bricks without the need for writing source code. Thus, even domain experts with rather few technical skills can assemble applications.
Furthermore, CBD is expected to have a strong impact on the quality of software development:
- Due to the simplicity, the software development speeds up. There is no need to develop everything from scratch because one can buy third-party components. The shorter development time results in reduced costs.
- Components enhance the reliability of the software, as they are improved, tested and debugged over years. Aside from this, the composer can choose and combine the best components of different vendors.
- The extensibility and evolvability of software systems is improved, because components can flexibly be substituted by another component that satisfies the requirements
A few years ago, this prospect led to a kind of euphoria in the software development community, as components were expected to solve a lot of problems. Now, some disillusion prevails. CBSD turned out to be very difficult, because software consists of many strongly coupled interacting entities, which cannot be wired together in a straightforward way.
Differences to Object Oriented Programming
Often, components and objects are confused or mixed up. Component Based Development indeed owes many concepts to object-oriented methods. Component Based Development as it is understood today, builds on OOP, but gives a more abstract view of software systems than object-oriented methods.
The principal difference is that components are totally encapsulated, as we have just seen. Components strictly prevent access to their internals, while in OOP knowledge about the objects' inner working is necessary, for example when inheriting from a class. This reuse mechanism in OOP is also known as white box reuse, because the source code is open for insight and modification.
Also, the building blocks' granularity is different: Components exist at different sizes varying from single objects inside a library to whole applications. In most cases, however, components are larger entities and contain several objects.
Composition Patterns and Software Architecture
A difficulty of OOP is the representation of interaction protocols. In object oriented programming, the global control flow is distributed over several objects. Therefore, modifications to the interaction protocols result in the change of several objects, which hinders the straightforward evolution of the system. Another problem is that the objects are only reusable in systems with similar interaction patterns.
Component technologies allow the representation of the architecture of software systems as reusable entities. Architecture Description Languages (ADL) describe a software system in terms of collaborations between abstract roles. A role is a kind of placeholder for a real existing component. At composition time, the roles are filled in with components by means of separate connectors.
The benefits are:
- Components contain fewer contextual dependancies and are therefore easier to transfer to other software systems.
- The interaction protocols can be reused.
- Software Architectures promote the creation of a well designed structure for the system instead of hacking the components together. A good structuring increases the maintainability of the software system, so that later changes can be undertaken more easily.
The JavaBeans Component Model
JavaBeans, the mainstream Java component Model, was introduced in 1996 by Sun Microsystems. It takes into account most important characteristics which constitute a component. JavaBeans are defined as follows:
"A Java Bean is a reusable software component that can be manipulated visually in a builder tool."
Together with the component model, Sun released a simple visual composition tool, the BeanBox. It is rather intended for experimenting with Beans than offering a professional IDE. For real world applications, one should better fall back on one of the Java IDEs like Visual Age or JBuilder that support the visual composition of JavaBeans, too.
As we can see, JavaBeans do not necessarily differ much from standard Java classes. That makes the beans component model quite easy to use. But JavaBeans can have some features most normal Java classes do not have:
- Event Communication
The requirements for an object to be a bean is to define a public parameterless constructor, so that beans can be instantiated by builder tools in an uncomplicated way (In the Point bean, the parameterless constructor is given implicitly). Secondly, one of the interfaces java.io.Serializable or java.io.Externalizable need to be implemented. The interfaces do not prescribe the implementation of any methods, but are an approval, that the bean may be saved in persistent storage as in a file or database. In doing so, the bean can be restored after an application was shut down or transferred across networks. The ability to store state of a component in persistent storage is called persistence. Java offers a standard serialization mechanism, what makes it very easy to serialize objects. Alternatively, component can be stored in a customized manner (e.g. in xml format) by implementing the Externalizable interface.
The properties of a bean are all fields that are accessible and modifiable by public methods. These getter and setter methods should be marked as such by following a certain naming scheme:
The accessor methods, on the other hand, are programmed by the pattern
public PropertyType get<PropertyName>()
The intention behind this naming convention is that it helps builder tools to find out how a bean works and what capabilities it has. As we have seen, a component has to provide information about its services, which is called introspection. Java Beans provides two mechanisms for introspection: reflection and the BeanInfo class. BeanInfos gives complex information about a Bean component, but have to be implemented explicitly.
JavaBeans interact with each other by means of events. Events are notifications, a component can give to other components, that something interesting has happened. An example for an event might be a mouse click on a button or the closing of a window. Beans can be source and target of events. To be informed about an event, a bean has to register at another Bean as a listener.
The Java event model realizes the observer design pattern with the effect that the inter-component coupling is reduced. Method calls require tight coupling, as caller and receiver need to know each other at compile time, while with events all communication happens solely via interfaces.
A special kind of event are PropertyChangeEvents. They are used to restrict some properties to take only specific values, for example for a month integer values between 1 and 31. Every time, such a bound property is modified, notifications to all registered PropertyChangeListeners will be send.
Customization is done via Property Editors. A property editor is a tool for customizing at design time a particular property type. Property editors are activated from so-called property sheets, which display all properties of a bean. If a property is selected for customization, the property sheet finds out the type of the property, displays the appropriate property editor with the property's current value.
A big strength of the JavaBeans component model is that it is designed for simplicity. Developing JavaBeans is very simple, because a lot of behaviour (like the platform independence or packaging mechanism) is supported in the Java Programming Language by default. However, one can optionally equip beans with additional objects like BeanInfos or custom PropertyEditors to use the component model in a more flexible way. A second facility is that Sun designed the whole swing GUI library according to the JavaBeans component model. Thereby Swing components can easily be composed in visual builder tools.
However, JavaBeans do not realize all features of a component model. A drawback is that JavaBeans are restricted to the Java programming language, while an important goal of components the independence of an implementation language is.