• Aucun résultat trouvé

Thinking Adaptively

4.1 KEY IDEAS

We relate adaptive software to important problem-solving principles: inventor's paradox, stepwise renement, and representation independence.

4.1.1 Inventor's Paradox

The \paradox of the inventor," posed by mathematician George Polya [Pol49], is one of the cornerstones of adaptive software. Polya observed that it is often easier to solve a more general problem than the one at hand and then to use the solution of the general problem to solve the specic problem. The hard work consists of nding the appropriate generalization.

Polya uses the following example to demonstrate the technique. Given a line and a regular octahedron, nd a plane that contains the line and that cuts the volume of the octahedron in half. What is important about the regular octahedron to provide for an easy solution?

The fact that it is a symmetric body is important. Given any symmetric body, the solution consists of choosing the plane that contains the given line and the center of symmetry. The general solution is easily applied to solve the specic octahedron problem.

What is the paradox? Why is it called inventor's paradox? It is a paradox because we would expect that solving a more general problem is harder than solving a specic problem.

It is called inventor's paradox because an invention needs to be done: we have to invent the proper generalization of the given problem.

Applying Polya's paradox of the inventor to object-oriented program design results in more adaptive programs being written, programs that adjust gracefully to specializations of the generalization for which they were designed.

In this book we introduce

adaptive object-oriented programming

as an exten-sion to conventional object-oriented programming. We adopt the convention that adaptive object-oriented programs are just called

adaptive programs

. Adaptive programming fa-cilitates expressing the algorithms that are essential to an application without committing to any particular data structure. Adaptive object-oriented programs specify essential data structure elements that constrain the conguration of any data structure that attempts to customize the adaptive program. This way, programmers are encouraged to think about families of programs by nding appropriate data structure generalizations, in the spirit of Polya.

In adaptive programming, the inventor's paradox has the following interpretation. The invention consists of inventing a generalized data structure for a specic data structure. The paradox is that it is easier to write programs for the generalized data structure than for the specic data structure.

Soon we will apply the inventor's paradox to writing an application for a travel agency.

Instead of writing the application for a specic travel agency, we will write it for an entire family of travel agencies, and the surprising news is that the generalization simplies the programming task.

4.1. KEYIDEAS 81

4.1.2 Stepwise Renement

The development of an algorithm is very often a complex process where the nal solution is achieved by stepwise renement. In every step certain details get specied which have been left open in the previous step.

Niklaus Wirth, circa 1970.

The idea of stepwise renement is another cornerstone of adaptive software. Adaptive software lets us write algorithms without knowing the detailed data structures and even without knowing the interfaces of the data structures. It is only after a renement step, called customization, where the data structures get fully specied.

Adaptive software uses a two-step renement method. First get the important parts of your application right and then worry about the accidental details of your data structures.

Readers might object that delaying commitments to data structures is a well-known approach to software development. What is the essential dierence of adaptive software to the other approaches? Adaptive software is written in two parts: the data part and the functional part, which are loosely coupled through constraints. This allows the same functional part to work with dierent data parts and the same data part can be matched with dierent functional parts. The adaptation occurs by a simple form of analogical reasoning that is rooted in a path calculus for class structures (see Chapter 7, Propagation Directives).

4.1.3 Representation/Interface Independence

The idea of making software independent of the details of data structures is another corner-stone of adaptive software. It is traditional in object-oriented software development to hide representation and implementation information. This comes out of early work of Parnas [PCW86]. Although we agree with the spirit of the information hiding principle, we feel that it is too restrictive. It is good to hide low-level representation information but it is not appropriate to hide essential logical information about object structure. It is good to make assumptions about the internal structure of objects! I have to repeat this twice since so many books and papers say the opposite. It is good to make assumptions about the internal structure of objects!

Sethi [Set89] summarizes information hiding with the informal

representation inde-pendence principle

.

A program should be designed so that the representation of an object can be changed without aecting the rest of the program.

We propose a stronger principle, the

adaptive programming principle

. A program should be designed so that the interfaces of objects can be changed within certain constraints without aecting the program at all.

The interface of an object is the set of functions that can be called for the object to manipulate its data. The adaptive programming principle implies that the program must be written parameterized by interface information. Indeed, an adaptive program is

82 CHAPTER 4. THINKING ADAPTIVELY

parameterized by constraints that say what kind of interface information is expected by the program. Therefore, an adaptive program does not completely hide all interface information of its local objects, but it exposes some essential properties of local objects.

By giving up strict information hiding, we surprisingly get better representation in-dependence. The reason is that adaptive software keeps only a loose coupling between functions and data expressed by parameterization constraints. The same program works for an entire family of representations that satisfy the constraints (see Fig. 4.2).

Adaptive programs are data structure-shy programs that are written in terms of hooks into a data structure (see Fig. 4.3). A hook means an important data structure element. The adaptive program is written in terms of paths between important data structure elements.

Data-structure-shy software opposes any attempt to encode too many data structure details into it. This opposition is enforced by a dependency metric that measures the dependency of a program on a specic data structure. The hooks may refer to data types or relations. Between the hooks there may be a lot of additional information that is ignored by the adaptive program although the information will be considered when the adaptive program is used in a specic context.

. .

. . . . .

. . . .

defines

compatible

selects selects selects Adaptive program C

Infinitely many class structures compatible with adaptive program C

An infinite family of programs defined by adaptive program C Figure 4.2: Adaptive Software

The need to program in a data structure-shy way has been recognized by others. In [GTC+90], we read

... the class hierarchy may become a rigid constraining structure that hampers innovation and evolution.