• Keine Ergebnisse gefunden

The method of our choice to implement the functionality indicated by the orthogonal properties de-scribed in Section 2.5.2 is influenced by a technique called mixin layers. Mixins are a programming style that was originally introduced by Flavors [Dav86], an extension of the Lisp programming lan-guage. Later on it was adapted to the C++ programming language (cf. [SB98], [SB00]).

In this section we would like to introduce the concept of layer based programming in contrast to the classical object-oriented software construction.

3.2.1 Multiple inheritance

In the traditional object-oriented software design, the subject of interest is modelled with classes.

Relationships between theses classes are modelled by inheritance or aggregation. This leads to a strict hierarchy in a software model.

For example, we construct data structures by writing classes which are subclasses of one or more other classes. If we want to accumulate functionality in a class, we need to specify all base classes (directly or indirectly) when we write this class. Thus, the inheritane tree is fixed and cannot be changed without rewriting the classes as we see in the example UML diagram in Figure 3.2.

A_1 A_2 A_3 A_n

...

B

Figure 3.2: Classical multiple inheritance

Multiple inheritance is supported for example by C++ and EIFFEL. However, not all object-oriented programming languages support the inheritance from multiple base classes. The designers of Java, for example, decided to restrict the language to only single inheritance, meaning that a class can inherit from only one base class. The reason for this restriction lies in two main problems which can arise when using multiple inheritance:

• Ambiguous methods in two or more base classes. A subclass intends to call a method, that is defined in more than one base class, cf. Figure 3.3. This type of error however, can be reported by the compiler. In EIFFEL, this problem is solved by redefining the according methods in the subclass. In C++, name conflicts are resolved by calling a member explicitly with the classname::membernameconvention (qualified call).

A + method1() : void

B + method1() : void

C + method1() : void

D + method2() : void

D::method2() {

method1();

}

Figure 3.3: Ambiguous methods

• Diamond inheritance, cf. Figure 3.4. If A is a virtual base class of B and C (that means, there is only one copy of A included in D), we have the situation that A::method() is called twice when we invoke D::method(). There may be cases where this is not the desired behaviour (cf.

[PSM97]).

C + method1() : void

D + method2() : void

D::method2() {

B::method1();

C::method1();

} A

+ method1() : void

B + method1() : void

Figure 3.4: Diamond inheritance

Although there are individual solutions to the above described problems, multiple inheritance stays a source of programming flaws, and every programmer has to use it with great care in his design. Thus, efforts were being made to linearize the inheritance, e.g. thephunctor approach in [PSM97]. Another approach are mixins.

3.2.2 Mixins

The problems with multiple inheritance are not the only drawbacks of classical inheritance in object-oriented programming languages. Another one is that a subclass cannot be defined without specifying its base class. This is overcome by the mixin programming construct (also referred to as abstract subclasses in [BC90]). The class a mixin inherits from, is specified at the place of instantiation, rather than at the place of definition of the mixin class.

Mixins classes are most commonly implemented usingparameterized inheritance. The idea is now to specify the base class as a (template) parameter. This concept is indicated in the UML diagram in Figure 3.5. The classes A 1,A 2, . . . , A n are now designed as mixin layers. They are not a part of a larger class hierarchy and thus can be written independently of other classes. The user/programmer now can linearly combine the components to bigger data structures that unite their functionality. In order to terminate the inheritance tree at the top, we need some normal base class at the end.

Base

A_n T_n A_3

T_3 T_2

T_1 T_3 T_n

A_1

T_1 ...

A_2 T_2

Figure 3.5: Mixin components

Remark 3.2.1. We would like to point out on this occasion, that UML class diagrams are not able to describe the mixin layer paradigm to the full extent. For example, UML doesn’t have a feature to clearly indicate that a class inherits from its template parameter. And especially for the possibilities of C++ concerning the implementation of mixin layers, it has no graphical analogon. Nevertheless, we try to illustrate the idea of mixins with example diagrams wherever it seems possible.

In C++ a mixin can be defined using template classes:

Mixin in C++

template <class T_1>

class A_1 : public T_1 {

... \\ class A_1 definition };

Mixins basically are intended to combine two solutions of modern object oriented software con-struction problems. On the one hand, the linearization of inheritance supersedes multiple inheritance, and on the other hand they allow the reuse of single software components without changing the class hierachy.

A_1 Base

A_3 A_2

A_n A_n-1 Base

B ...

A_2 A_1

Figure 3.6: Example mixin composition

3.2.3 Mixin layers

Mixins layers are a variant of the mixin technique, intended for constructing arbitrary complex data structures out of small components. These components might be assembled in (nearly) any combina-tion and order. Mixin layers were proposed in [SB98] as an implementacombina-tion technique forcollaboration based designs. Collaborations are a method to describe interdependencies of objects in an object-oriented design. A set of objects and protocol of interaction form a collaboration. The part of an object that satisfies a protocol of a certain collaboration is called the object’s role in the collaboration.

An object can now participate in different collaborations as well as different objects can participate in the same collaboration. A whole software product is then defined as the composition of different (ideally) independent collaborations.

In [SB02] it was suggested to implement mixin layers in C++ using nested classes to represent the different roles:

Mixin layer template <class BaseLayer>

class Layer : public BaseLayer {

public:

class FirstClass : public BaseLayer::FirstClass {

...

};

class SecondClass : public BaseLayer::SecondClass {

...

};

...

};