Patrick Steyaert, Carine Lucas, Kim Mens
Programming Technology Lab
Vrije Universiteit Brussel
Pleinlaan 2, 1050 Brussel, Belgium
Tel: (32) 2-629-3581
Fax: (32) 2-629-3525
Email:
prsteyae@vnet3.vub.ac.be
clucas@vnet3.vub.ac.be
kimmens@is1.vub.ac.be
While object-orientation has had a large impact on the popularisation of reuse, reuse in OO is mostly ad hoc and lessons can be learned from the work on systematic reuse. On the other hand, the emphasis of object-orientation on iterative development is important because it allows the construction of reusable assets in a bottom-up fashion. We claim that systematic reuse needs to be reconciled with iterative development in order to make reuse a standard practice. Such a reuse methodology must emphasise the co-operation between asset providers and asset reusers to control how assets can be reused, how assets are reused and how changes propagate from assets to applications during iterative development. We propose reuse contracts as the basis for such a methodology.
Keywords: Reuse contracts, change management, iterative development, object-orientation.
Workshop Goals: Cross-fertilisation between the OO community and the reuse community, get feedback on our ideas on reuse contracts from the reuse community.
Working Groups: Object Technology, Architectures, and Domain Analysis; Domain Engineering Helps Manage Change.
The Programming Technology Lab is involved in a number of research initiatives that aim to solve mostly technical problems that prevent the establishment of systematic reuse. Both our inspiration on which problems are most important to solve and the validation of our work come from joint projects with industrial partners. These projects are mostly aimed towards the development of frameworks for vertical markets (broadcasting planning, hypermedia, group decision support systems, ...). While before our work mainly focused on implementation aspects, our current goal is to develop a methodology for systematic reuse that covers all phases of the life-cycle and has a strong formalisation, as well as a practical applicability.
It is often claimed that artefacts created with object-oriented techniques are, by their very nature, more reusable than artefacts created with conventional means. Consequently object-orientation has had a large impact on the popularisation of reuse, and object-oriented methods hold many promises for making reuse a standard practice. However, because of the opportunistic - ad hoc - nature, the reuse potential obtained with object-oriented methods alone, leads to marginal gains only. The reuse community has emphasised that to obtain more substantial gains, a more systematic approach to reuse is necessary. Systematic reuse requires a shift from crafting one system at a time to the use of engineering principles for entire families of systems. However, object-oriented software engineering has been traditionally concerned with the development of custom built single systems. So, none of the currently used OOA/OOD methods [1], [2], [3], [4], [5] are suited for this kind of systematic software reuse.
We therefore suggest a methodology that combines the best of both worlds by introducing systematic reuse in the OOSE process. An important problem is how to reconcile the principles that underly systematic reuse with those that underly iterative development in OO. Such iterative development is important because it allows the construction of reusable assets in a bottom-up fashion. This is crucial for reuse to become economically feasible: it allows finding a delicate balance between the longer term investments needed for constructing reusable assets and the need to meet shorter term (customer) deadlines. Our conjecture is that incrementally building reusable assets requires a strong co-operation between providers of reusable assets and asset reusers. Therefore, we propose a methodology that represents this co-operation by an explicit contract and complies to the following criteria.
Systematic reuse is based on building models that are reused in a disciplined manner. So, in contrast with what is customary today, ``design reuse'' does not simply mean taking an existing design, copying it and modifying it to some particular need, but rather the development of a design model of our software that can be reused in a disciplined fashion. Still, in current OOSE methodologies the issue of disciplined reuse of analysis and design as well as programming artefacts is almost entirely neglected.
While reuse should not be ad hoc, it should not be too coercive either. A developer of reusable assets should provide a reuser with specifications that are powerful enough to enable reuse, while not overconstraining the reuser. For example, the typical black box reuse mechanisms that are so popular these days are considered too coercive, because they do not allow reusers to adapt their components before reuse.
Systematic reuse should not only recognise the need for a reusable asset to evolve both during its initial design and when it is being reused, it should actually advocate the development of a methodology for managing change in the process of engineering reusable software. The development of reusable assets is inherently an evolutionary process. It requires a number of iterations of building/modifying the asset and reusing it to see if it is properly reusable. On the one hand, this requires that reusers provide feedback on how assets are reused and on how reusability could be improved. On the other hand, it requires an advanced change management mechanism. With evolving assets there is always the danger that a proliferation of versions occurs. While systematic reuse should present an opportunity to reduce maintenance effort, a proliferation of versions increases it, as older versions of an asset behave differently than newer versions. The absence of change management mechanisms is recognised as an important inhibitor to successful reuse [6], [7], [5].
Much of what is currently being proposed for object-oriented software reuse (frameworks, design patterns,...) lacks formal notation and rules. There is, for example, a general understanding that a framework may only be reused in a pre-defined way: the basic framework structures may not be violated. The rules to do so remain informal documentation however. When using only informal descriptions of reusable artefacts, reasoning about, for example, how to reuse an artefact, effort estimations, or the impact of changes to reusers can only be done by error prone informal reasoning and no discipline in the reuse of artefacts can be enforced. Disciplined reuse requires models expressed in a formal notation and formal rules on how to reuse an artefact based on such models.
On the other hand, reusable artefacts are preferably reused by as many reusers as possible. This means that they need to be expressed in terms that are understandable by reusers. For example, the models that are used early in the life-cycle at the analysis phase must be expressed in terms that are understandable to end users. Moreover, different models are needed for the same artefact ranging from very abstract models for quick assessment of the feasibility of reuse to detailed models for the actual reuse. This suggests some form of layering.
The art is in finding the right balance between descriptions that are easily understood and expressed, and descriptions that capture enough of the semantics of the asset being built and reused.
In the next subsection we propose reuse contracts as a methodology for systematic reuse that respects these criteria.
Based on the problems described above, it is our conjecture that substantial reuse requires a strong and well-defined co-operation between asset providers and asset reusers. We therefore suggest the introduction of explicit reuse contracts [8]. The asset provider must document that part of an asset that is relevant to reusers, while reusers must declare how an asset is actually reused. When reuse is based on such a formal contract, reusers can profit from the changes made to reusable assets because formal rules can be defined that facilitate change propagation. Providers can profit from the information given by reusers to make their assets more reusable. This not only solves the maintenance problem, caused by the proliferation of versions, but also assists in the iterative development, as crucial feedback from reusers is made available to the asset developers.
Because the best-known object-oriented reuse technique today is undoubtedly the use of abstract classes with inheritance, in [8] we focused on the problem of reuse of class hierarchies as a more tangible case to express the ideas behind reuse contracts. In that case, a reuse contract documents the design of a class by means of its specialisation interface [9]. This information is used by reusers to decide which methods have to be overridden and which methods can be inherited. Furthermore, reuse contracts can only be changed by means of formal reuse operators. These encode the different ways a class can be reused and adapted: extension, concretisation and refinement are ╥design preserving╙ operators and their inverses: cancellation, abstraction and coarsening are ╥design breaching╙ operators. Although not the only operators imaginable, they do coincide with the typical ways to reuse abstract classes. Together, reuse contracts and reuse operators record the protocol between providers and users of reusable assets (in this case, abstract classes). Simple formal rules were defined that signal possible conflicts in existing reusers (inheritors), when changes are made to the assets they are reusing (parent classes). Most of the possible conflicts can be directly expressed in terms of reuse contracts and operators rather than on the level of interfaces and calling structures. This allows developers to reason about change in more intuitive terms and on a higher level than previously possible. As reuse contracts can only be adapted by means of certain predefined reuse operators, reuse is disciplined. Moreover, since we also included design breaching operators, reuse is not too coercive.
Because conflicts upon change can be easily detected, reuse contracts help to predict the work effort in updating existing applications. Because they document what aspects possible reusers can rely on, they can also be used by developers of a reuse library to decide whether making a certain change to the reuse library is a good idea or not. In the same vein, conflict detection rules can be used to guide application developers both in understanding where testing is needed when the reusable asset has changed and how to fix the problems.
Up until now, reuse contracts were only fully developed for the reuse of classes in an inheritance hierarchy. Early results on the application of the same principles to reuse of multi-class components and state chart diagrams, however, show a lot of promise regarding the scalability of the approach. Similarly, while this first experiment with reuse contracts mainly concentrated on implementation conflicts, current work is being done to apply the same ideas to the earlier life-cycle phases. These preliminary results support the premise that reuse contracts have a lot of potential as a general reuse methodology.
As was already mentioned in section 2.1 most state-of-the-art object-oriented reuse methodologies are insufficiently formally supported. This is e.g. the case for object-oriented frameworks [10], [11] that are usually documented through very informal documents. One way to additionally document frameworks is through design patterns [12], [13], [14], but these suffer the same lack of formal underpinnings. Cookbooks [15] that guide reusers step by step in the reuse process (the ``customisation'' process for frameworks) were suggested as another approach, but these suffer from the additional problem that they are overly coercive, i.e. they can only guide reuses that were specified up front. Reuse contracts provide a formally underpinned documentation, that still allows enough flexibility.
While, up until now, the issue of disciplined reuse was almost entirely neglected in object-oriented analysis and design techniques, recently new concepts as facades and variation points [16] were introduced to tackle this problem. These approaches try to discover possible points of evolution at the earliest phases of the life-cycle and incorporate them in the design. While a good starting point, we believe that a complete methodology should also incorporate the handling of unforeseen reuses and adaptations. That concern is one of the main contributions of reuse contracts to these other methodologies.
Patrick Steyaert holds a post-doc position at the Programming Technology Lab at the Vrije Universiteit Brussel, where he received his PhD in 1994 with work on object-oriented programming languages, reflection and semantics. His current interest is in the integration of reuse contracts in existing object-oriented modeling techniques and the development of a methodology for the iterative development of reusable assets.
Carine Lucas is a teaching assistant and researcher at the Programming Technology Lab at the Vrije Universiteit Brussel. She received a Licentiate Degree in Computer Science from the Vrije Universiteit Brussel in 1991. While before she conducted research in design and typing of object-oriented languages, her PhD will focus on the use of reuse contracts for implementation, maintenance and refactoring of OO software systems.
Kim Mens is a teaching assistant and researcher at the Programming Technology Lab at the Vrije Universiteit Brussel. He received a Licentiate Degree in Mathematics from the Vrije Universiteit Brussel in 1992 and a Licentiate Degree in Computer Science from the same institution in 1994. He has previously been working on object-oriented programming calculi and on typing of object-oriented programming languages. His long-term research goal is to develop the formal foundations of a general reuse methodology, based on the concept of reuse contracts.