This chapter explains with more details the concept of reuse in the domain of software engineering. This notion can be considered differently at each step of the development process of software, and we present here different techniques that can be used to allow reusability at different stages in the life cycle of software. Previously, we saw that the concepts contained in the OO paradigm are particularly well adapted for this purpose. Now, we introduce a complementary approach of software engineering called "component-based software development" (CBSD). The aim of such an approach is to enable the systematic design of reusable components. The combination of the OO and the CBSD technologies offers full of promises for software reuse. However, due to the newness of these concepts, there is only few software in the field of discrete-event simulation that implements both of them. In fact, from our knowledge, the Visual Simulation Environment (VSE) is the only software that actually integrates completely these two concepts. For this reason, it is difficult to find references of any work dealing with reusability in simulation. This explains why this chapter presents reusability only in the general context of software engineering. In a first part, we discuss the concept of software reuse, its benefits, the means it needs and its potential drawbacks. Then, we present some techniques of software reuse, at different steps of the development process. Finally, we introduce the new concept of component-based software.
As presented in [Leach 97], "reuse can be defined as using what already exists to achieve what is desired". In the life cycle of software, reusable parts can be artifacts of the analysis, the design or the programming (source code or object code). In this chapter, we call them "components". But, in the rest of the report, the term component refers to the definition we will give when presenting the concept of component-based software. Efficient reuse of a component implies to know where to find it, what it performs and how to use it properly. That supposes to dispose of a way to catalog the potential reusable components ([Leach 97]) and a good documentation for each one ([da Silva 96]).
The reasons commonly presented for the apparition of software reuse are that it increases the productivity of software, by reducing the development time and the number of employees. Then, it also increases the quality of the software built and facilitates its maintainability. Another reason is that computers all around the world tends to be progressively all connected and form a large information system ([Williams 98]). The connected computers share data, but also more and more the software. So, the importance of reusing components here grows continuously. However, "reuse is beneficial only when the cost of building and maintaining a new component is greater than the cost of acquiring and adapting an existing component and maintaining the combination of code" ([Stroustrup 96]).
The following criteria, presented in [Coulange 98], must be considered before using a reusable component or when designing one.
In the life cycle of software, a lot of components are desired reusable. We just present here some of them, in order to precise the possibilities the term reuse implicitly means.
To conclude, there is language-independent reuse, such as the reuse of design and analysis, and language-dependent reuse such as the reuse of object or source code. B. Stroustrup underlines that language-independent reuse usually conduct to a grow of the execution time and space needs that can not be acceptable after several levels of reuse. For this reason, Stroustrup sees "language-independence reuse as a more viable approach to large components with few interactions than for smaller components with frequent interactions or strict performances characteristics" ([Stroustrup 96]).
[Leach 97] presents the typical members a reuse team must contain to be efficient. This underlines the importance of the documentation.
We introduce here briefly some methods used for software reuse. As we seen before, there are different kinds of component that can be reused in software. So, we try to present methods for each of them. We start with the reuse of analysis and design components. Then, we discuss the problem of portability and the need of a standard programming language. After that, we discuss techniques for designing directly reusable components, and especially in the case of an OO language. Finally, we underlines the problem of safety induced by reuse, and the importance of the documentation for software reuse.
Most researchers in software reuse believe that domain analysis is a requirement for a successful reuse program ([Leach 97], [Cohen 98]). Domain analysis is a generalization of system analysis. System analysis consists in the study of a particular system, whereas domain analysis considers all the systems of a particular domain and tries to define the common elements, building a vocabulary for the domain.
Designers and programmers are usually confronted to the same kind of problem several times in their life. The aim of software reuse is to avoid them to "reinvent the wheel" every time. For that, the notion of design pattern appeared ([da Silva 96], [Schmidt 96]). A design pattern is a reusable element of design. It is independent of the domain of application. It offers a generic solution for a particular kind of problem. Although a design pattern is independent of the language used further for the programming, it is dependent of the approach chosen for the design. For instance, [Gamma 95] presents an interesting set of design patterns providing design solutions for the OO approach. Design patterns are expressed in a standard formalism ([Gamma 95]). Usually, an example introduces the problem. Then, the generic solution is presented independently of any domain of application. For that, formalism specific to the design approach is used. For instance, design patterns for the OO approach will be presented with class diagrams. Then, an implementation of the solution in a particular language can be proposed to illustrate the modeling and the use of the solution. Finally, the drawbacks and the advantages of the solution should be discussed. Usually, design patterns are largely documented. Hence, the user can completely benefit of the experience of the designers that propose a design pattern.
When presenting some examples of reusable components, we saw that the language-dependent reuse can imply a lot of problems. This kind of problem is related to the criterion of portability of a language. The more a language is portable, the easier a component can be reused from a machine to another in this language. So, the language everyone dreams about is a fully portable one used by everybody. That will avoid all the problems of portability and totally suppress the notion of language-dependent reuse. In this aim, the Java language has been developed and seems full of promises ([Niemeyer 97]). This language is supposed to run on every machine without any problem of portability. In fact, instead of preparing the object code in the machine language like a lot of languages, this language compiles the object code in a pseudo machine language. Then, fast algorithms, dependent on the machine can interpret this pseudo object code and execute the program. Hence, the problems of dependency are moved in the only design of these interpreters. Then, every machine having a Java interpreter is able to run a program from any other sources. Of course, the performances of such languages are not as good as classical compilation languages, but they still acceptable for a lot of applications. Moreover, Java is used for Web applications and is, by this way, extremely well placed to become a universal language.
We will discuss here different ways to design reusable components. We could present them in a large context, without mentioning any particular approach or language. However, we partially agree with B. Stroustrup. In [Stroustrup 96], he explains that it is difficult to discuss reuse without considering the language that will be used. We thing that it is not always necessary to consider the language, but the approach used for the design seems fundamental to be fixed, before detailing any techniques of design for reuse. So, in this section, we will focus our presentation on the possibilities of the OO approach. A complementary approach, the component-based software, is next presented separately in this chapter. Classical languages propose, for reuse, only the concept of library, which contains functions, data and data types that can be reused in another program. Libraries have some variants and various names like package or module. In an OO language, the notion of library remains, but the reusable components in it are a bit different. We can find functions, metafunctions, classes, metaclasses, types and interfaces that can constitute frameworks. We present here the concepts of OO that contribute to the reuse of those components ([Leach 97], [Stroustrup 96], [Coulange 98]).
The concept of genericity we have presented with the instantiation relationship (cf. the chapter about the OO approach) is a powerful way of reuse. It allows the reuse of data structures and algorithms for any data type. For that, metaclasses and/or metafunctions are defined, like a normal class or function with the only difference of not knowing the type of the data they manipulate. It is part of their parameters. By this way, generic algorithms and classes are defined. They can then be instantiated for any type of data (of course, the data type must fit some constraints induced by the way the generic class or the generic function uses this data type).
Classes defined in a library can be reused two different ways: direct instantiation or inheritance. If the class reused is perfectly adapted, instances of it can be used in the program. It is the first and natural way of reuse of a class. Then, it is also possible to adapt the class if its behavior does not totally correspond to the need of the current application. In this case, the class is reused by inheritance and specialization.
With the OO paradigm, full applications can be considered as objects and described by a class. That means a user can reuse a complete application, modify and adapt it by inheritance. Some examples of applications that can be reused are text editors, files managers, pictures editors... This kind of reuse is common in the Java language. For instance, the small applications embedded in HTML files, called "applets", can be considered as complete applications and it is usual to reuse them in different documents.
Abstract classes or interfaces (cf. the chapter about the OO approach) can be elements of reuse. They represent a type of object, but only indicate how to use such objects. They just present the set of methods such objects possess. How each method is performed is not defined. The programmer who reuses the interface must define its implementation. However, an interface is usually associated with a set of functions or classes that manipulate this interface. If the user uses the interface and defines a class of objects from it, he can then use the functions and classes that manipulate the interface.
A framework is a set of components: functions, classes, interfaces and types. They constitute a particular functionality. However, there still some abstract classes, so some specialization is expected. In fact, a framework gives most of the functionality required for a generic problem or mechanism. But some elements are specific to every particular problem, so they still undefined in the framework. That is why the programmer must specialize abstract classes to insert the particularity of its design in the whole mechanism proposed by the framework.
The problem of the documentation in software reuse is extremely important ([da Silva 96]). We begin to underline it when presenting the typical members of a reuse team. We saw that reusable components must be cataloged. It is the first step of the documentation. When a programmer has a problem, a rapid search in a database must indicate if a reusable component exists. Then, when finding it, the programmer must learn how to use it and be sure that what the component performs is what he wants. [da Silva 96] proposes that the following information should be specified for each reusable component.
An important problem arises with software reuse that usually is not really considered. When reusing code from another person, how to be sure this code is not harmful ([Waldo 98]) ?. If you trust the person, there will be no problem, but if you buy your component from an unknown person or download it from a Web site, how to be sure it is harmless ? Unfortunately, lots of software do not even consider it. But, in some new languages, an authentication mechanism is provided. For instance, in the Java language, there is a way to authenticate the provider of a reusable component by encryption with public and private keys ([Niemeyer 97]).
The concept of component-based software is to consider software as an assemblage of interacting components. This concept of designing and implementing software systems as a set of components is nothing new. Such an approach has gained in popularity for at least three decades. However, what is new is that large-scale software development is increasingly achieved through selection, evaluation and assembly of components from various external sources. [Brown 96] presents the following factors to explain the growing consideration for this approach.
This kind of software development implies two kinds of company ([Clements 96]). There are companies that use reusable software components and buy them, like a producer of electronic devices will buy chips. And there are companies that design the reusable software components and sell them. Of course, the CBSD means different things for each of them. But both of them must work together to define standards and systems that support the CDSD.
The way of thinking software applications is different with CBSD. Part of the work consists in conducting a study about which components reuse from external sources. The market for reusable components must be analyzed, components compared... In fact, the choice of a component is not so easy, and to guarantee the achievement of the software, a careful analysis must be done ([Clements 96]).
For the provider, there is no fundamental change in the way it designs software. Its challenge is to finally provide reusable software. For that, the investigation of the needs of the potential customers must be maybe more important than with a classical software development.
Software reuse seems full of promises, but implies important problems ([Leach 97]). The processes of finding, understanding, modifying and integrating the components in a software application are more difficult than they seem to be. Then, a company that wants to start with this new policy will be confronted to the problem of high initial costs. Finally, several legal and contractual issues arise like the liability in the case of failure of a reused component, the ownership of reused components... In this presentation, it appears that the documentation stills an important aspect of software reuse and is known to be a part usually under considered during software development. Finally, the idealistic way to exploit fully software reuse is to define a standard language every machine can understand. That will avoid many of the problems. Concerning VSE we will see in the next chapter, it integrates both the OO technology and the CBSD. In fact, VSE allows representing visually components. By this way, components from an existing model can be reused in a new one just by selecting it and placing it graphically in the new model.
|