neering means constructing a new system in terms of interacting, distinct ..... Send Mail. Load. Drive. Unload. Confirm Delivery. Input Mail. Figure 4: Mail Delivery ...
Components vs. Objects Luigia Petre
Turku Centre for Computer Science TUCS Technical Reports No 370, October 2000
Components vs. Objects Luigia Petre
Turku Centre for Computer Science TUCS Technical Report No 370 October 2000 ISBN 952-12-0740-X ISSN 1239-1891
Abstract Component-based software engineering means constructing new systems from already existing, service-providing components. Object-based software engineering means constructing a new system in terms of interacting, distinct units of information and services called objects. Both components and objects have encapsulation properties and are accessed via well-de ned interfaces. Both components and objects are considered to improve the reuse of software and to alleviate its evolution phase. Finally, both notions are thought of being natural abstractions of real-world entities. Moreover, a real-world entity can be modelled or implemented using either notion. Their similar appearance in abstract modelling gives rise to confusion in distinguishing between these two notions. In this paper we examine the conceptual dierence between components and objects, and aim at clarifying it. Based on this, we also propose a guideline for a software engineering process that incorporates both notions and exploits components and objects at their real potential.
Keywords: Software Engineering, Components, Objects.
TUCS Research Group
Programming Methodology Group
1 Introduction Components and objects are concepts very often encountered in current software engineering terminology. By using them, bene ts like natural software abstraction, reuse, easier evolution, or encapsulation are aimed at. Both components and objects can be seen at certain granularity levels as black boxes providing some services via well-de ned interfaces. Both of them can be even used in modelling the same system. Their common goals, similar structure and likely bene ts rise the question of their dierences. More precisely, two main questions are to be answered:
What is the essential dierence between components and objects? (Why) do we need them both?
In trying to answer to these questions, we examine the conceptual dierence between components and objects and aim to clarify it. Based on this we propose a guideline of how to make use of both notions during a software engineering process, in order to exploit their advantages in a proper manner. An example emphasising the dierence as well as the guideline is also provided. The question of comparing components and objects has appeared before [14, 13], most notably in [8]. However, the result of such a discussion left students and programmers alike with controversities. Moreover, even academics seem not to perceive clearly and arguably to what degree can we dierentiate the two notions. The people who can dierentiate components and objects work in a certain application area with particular strategies for software construction or analysis. These strategies embed certain interpretations of components and objects [13]. Or, they are highly trained academics that are so involved with the matter that consider this debate unnecessary [14]. Either category, we consider it generally useful to take a more systematic analysis of components and objects. In this paper we consider some classical description of these notions and, based on it, we analyse components and objects following the criteria of usage, reference and nature. The result of the analysis can be summarized as follows. Components and objects are essentially dierent and quite advantageous to be used together in constructing large software products when following certain patterns. Consequently, the contribution of the paper consists in separating these two software engineering concepts towards the bene t of better using them in a software construction process. Overview. In sections 2 and 3 we shortly describe the component concept and the component-based software engineering, as well as the objects and 1
the object-based software construction, respectively. In section 4 components and objects are analysed in parallel, pointing out their key dierences. Section 5 proposes a software engineering process that makes use of both concepts. Finally, the conclusions are presented in section 6.
2 Components The component-oriented [9, 14] style of programming consists in developing software components as well as in assembling new software systems from them. The software component term has been coined about three decades ago as a logical solution to the software engineering crisis [9]. This notion was based on an analogy to plug-and-play inter-operability available to producers and consumers in other engineering elds. The foremost bene t of having a component-based software industry consists in the reuse of software that it provides for. Moreover, component-based software products are claimed to have an increased exibility and robustness, as well as a shortened time to market. The component-based development is not widespread yet, but the experience of thirty years is now used to ground it as a fundamental software construction method [14, 13]. Software components were de ned by Szyperski in [14] as \units of composition with contractually speci ed interfaces and explicit context dependencies only". In addition he states that \a software component can be deployed independently and is subject to composition by third parties" [14]. From this de nition we can resume components as speci ed by one party, implemented by another party, and nally used by a possible third party. The third party uses the component being based on the speci cation of its interfaces and has no information about the actual implementation of the component. Components are binary units providing the implementation of the services speci ed in their interfaces. The speci cation of an interface is contractual, i.e. it binds together a user of the interface and a provider of an implementation of the interface in a balanced manner. The contract of the interface should be precise enough to specify the functionality of the latter but also non-deterministic in order to allow the provider of the implementation to choose its own solution. For providing the required functionality, a component may need additional system support or other services from other components. All these requirements are clearly speci ed in a contractual manner as context dependencies. Components using interfaces from each other are said to be composed together. The result is a component-based software system that, in its turn, provides some functionality using the collaboration of the participating components. A system built this way is more 2
Driver
Drive
Post Vehicle
Load
Transport
Send Parcel MDS Confirm Delivery
Figure 1: Mail Delivery System (Component View) robust, as it is formed of smaller components, already tested by the market (re-used), and thus themselves robust. As the system speci es only the required services of the participating components, the exibility of the system is increased by the possibility of replacing old and less ecient implementations with new and more performant ones. This issue also provides for a smoother evolution of the software product. Finally, the time to market is shortened since only the speci cation of the required services and the assemblation of the components implementing them has to be performed. As an example of a component-based system, consider a mail delivery simulation. Of the three components participating in the system, Mail Delivery System (MDS), Driver, and Post Vehicle, the former uses the services of the latter two. The system is required to send parcels to their destinations as well as to con rm their delivery. The component MDS implements two services, SendParcel and Con rmDelivery and requires the services Drive and Load (parcels), implemented here by the Driver component, as well as the service Transport, implemented here by the Post Vehicle component. In Figure 1, the interacting components and their interfaces are represented using a UML component diagram [2].
3 Objects The object-oriented [3, 7] style of programming consists in developing applications built of objects that communicate with each other in order to solve the programming task co-operatively. Each object is delegated with speci c and narrow responsibilities and thus, one advantage of the object-oriented (OO) approach consists in its modularity. The OO-approach originated in OO programming [5] and gained its rst big success with the programming [6] of graphical interfaces. Later, it was generalized to many areas, such as distributed systems [11] and databases [4], software engineering [2], arti cial 3
Engine
Driver Outage
Task
0..1 On leave
* Post vehicle drives
Wheel
0..1 y dut
On
Door Bus
Car
Truck
Figure 2: Mail Delivery System (Object View) intelligence [10, 16] and information systems [15]. The main bene ts of an OO-approach to a software product consist in the fact that the objects underlying the problem domain are rather stable elements. Hence, an OO-approach to a software product anticipates the need of the latter to evolve and favours solutions that ease this evolution, encouraging the re-use of software. Conceptually, an object is an abstraction from a real-world entity, that can have associated items of information and can be manipulated by a set of operations, speci cally applicable to it. More precisely, an object is an abstraction of a data item characterised by a unique and invariant identi er, a class to which it belongs and a state, represented by a simple or more complex value. The class de nes the behaviour of the object. A class is an abstract data type characterised by a set of properties (attributes and operations) common to its objects, together with the means for creating objects with these properties. The state of an object cannot change spontaneously but only as a consequence of operations performed on it. The set of all objects created by a class form the class extent. A class (subclass/derived class) inherits from another class (superclass/base class) if the subclass extent is a subset of the superclass extent. The objects in the subclass extent must support all the operations that are supported by the objects in the superclass extent. However, the objects in the subclass extent may carry out these operations in a speci c way and they may also have additional operations. Objects can interact by using each others operations. They are not allowed to directly access other object states. The implementation of object operations is also hidden from other objects. An OO-software system is modular, due to the collection of objects that participate to it. Each object is concerned with its own responsibilities and is constrained by the properties of its corresponding class. Provided that a suitable class decomposition was found for the system under development, 4
focusing on classes construction rather than on the system as a whole eases the software engineering process. Moreover, as classes are abstract data types, generalization relationships between them (inheritance) improve the reuse of design and implementation. Also it seems that objects modelling real-world entities are quite fundamental and stable. This fact, together with the hiding of the implementation from other objects contribute to an easier evolution phase for the considered product. As an example of an object-based system consider the class diagram in Figure 2 that underlies the example also used in the previous section. The Post Vehicle class is composed of three other classes, i.e. Engine, Wheel, and Door. It can also be specialised to dierent classes of vehicles, such as Bus, Truck and Car. A Driver class has an association relationship with the Post Vehicle class denoting that the Driver instances are allowed to drive several Post Vehicle instances. Two other association relationships of the class Driver denote that its instances can be on at most one leave at a time (for instance on holiday or on a sickness leave) and have at most one task to perform at a time (for instance of transporting the mail to given destinations). In Figure 2 these classes and their relationships are shown using a UML class diagram [2].
4 The Conceptual Dierence Given the traditional description of components and objects as shown in the previous sections we can notice some common features these notions support. Thus, both of them have encapsulation properties and are accessed via wellde ned interfaces. Both components and objects are considered to improve the reuse of software and to alleviate its evolution phase. They are thought of being natural abstractions of real-world entities. Moreover, a real-world entity can be modelled or implemented using either notion, see Figures 1 and 2. In trying to dierentiate between these notions, some intuitive grip can provide further insight. We might say that components are bigger entities than objects. We might also argue for components being more suitable entities for software architecture (an early software engineering phase) while objects are more suitable in the implementation phase (late software engineering). However, none of these arguments are appropriate, since they depend on the size of the project. At dierent granularity levels, objects can be used for software architecture and components for implementation. Moreover, as we admitted that the same real-world entity can be modelled with either notion it is dicult to say what does it mean that components are bigger 5
than objects. What we believe to be the signi cant dierence between components and objects relies in their roles. While objects are suitable for describing realworld entities, components are suitable for describing the services of realworld entities. That is, objects are suitable for describing the problem domain of a system, while components are suitable for describing its functionality. From this perspective, the objects of a system partition the state space, while the components partition its service space. Expressed dierently, the syntagm `components vs. objects' can be understood as `service vs. identity'. Service vs. identity refers in fact to the manner of using services from components and objects. Using a service from a component means to specify the required service and to use any component providing an implementation of that service. Using a service from an object means to specify which object is to be used and to use the service that particular object, with its particular state, can provide. As an example, consider a software project that uses the services of a Driver component. In fact, this project requires a component that is able to drive dierent types of cars, for a speci ed amount of time, and requires a salary of no more than x . The identity of this component is of no interest for the project as a whole. In an object-based project we might have a hierarchy of classes specifying drivers, some of them more skilled than others. In this case, it is the identity of the object, or the class to which extent the object belongs to, that determines what services a particular driver d 007 can perform for the project. The object-orientation can be considered as a more mathematical approach to software. In fact, a dedicated theory of objects [1] has been recently developed, that takes the concept of object as primitive and focuses on the rules objects should obey. Object-oriented concepts like self, dynamic dispatch, classes, inheritance, prototyping, subtyping, covariance, contravariance, and method specialization are captured by this theory. On the other hand, the component-orientation can be seen as a more engineering approach to software. In fact, software components have a particular nature that combines mathematical, engineering and market aspects [14]. Their engineering dimension comes from the basic concept behind them - that of building systems out of already built parts or components. The syntagm `components vs. objects' seen as `engineering vs. mathematics' should hence be understood in a broad sense. That is, objects can model the problem domain of a system in a similar manner to mathematics oering abstract models of the world. From the same perspective, components can model the functionality of a system in a similar manner to engineering disciplines oering practical solutions to problems or realizing the functions some systems have to perform. 6
Summarizing, apart from the above more intuitional syntagm `engineering vs. mathematics', the initial syntagm `components vs. objects' should be regarded as `service vs. identity' or perhaps `service vs. state'. For distinguishing between these notions we can associate a component with the set of services it implements, and an object with an identity together with a set of properties (attributes and operations) it has. Based on this, we show in the following section how to use both concepts in a software construction process.
5 Using Components and Objects We have argued before for components to be considered as service-oriented. This view implies that components can describe best the functions a system has to perform, that is, the functionality of a system. On the other hand, objects can be considered as identity-oriented and hence they can describe best the problem domain of a system. We are interested in using these properties of components and objects in a pattern for developing (large) software products. In the analysis phase the speci cation of a software system comprises only its required functionality. Therefore, it is not easy nor natural to depict a suitable class decomposition of the problem domain. Instead, it is natural to see the system as a collection of services it should provide. Consequently, as many of these services are usually related to each other, we can group them conveniently. In this way we determine a set of components, each component implementing a group of services. These components have to be constructed, or, if they already exist, simply re-used. Excluding the already existing components, we end up with a set of components to construct, for which the services are well-documented. The design of each component basically consists in determining the services to be used from other components and the services to be implemented by that component. In order to implement the services, a suitable object-oriented decomposition providing the required implementation has to be found. At this stage, the object-orientation is not mandatory, but the experience shows that such an approach is more intuitive and stable, withstanding the evolution of the software system better [7]. Moreover, nding a suitable class decomposition for a focused part of the initial system (i.e., one component) is considerably easier. We note that this approach agrees with the intuition had so far. More precisely, components are to be used as software architecture means, while objects are to be used at the implementation level. Nevertheless, for a software project requiring only one component, its associated class decomposition 7
Drive
Send Mail e>
Confirm Delivery