Adapter pattern

The adapter (english adapter pattern ) - the shell class or wrapper called ( v. Engl wrapper, packaging ',' envelope '. ) - Is a design pattern in the field of software development and belongs to the category of structural patterns ( engl. structural patterns ). The pattern used for the transmission of an interface to another. This ensures that communication in classes with mutually incompatible interfaces is possible. It is a design pattern known as GoF patterns ( Gang of Four, see Gang of Four ).

  • 5.1 General
  • 5.2 Class Adapter 5.2.1 A concrete example in C

Use

The adapter is used when an existing class to be used, the interface does not match the required interface. This occurs particularly when classes that are designed for reuse - to be used - such as toolkits or class libraries. These provide their services through well-defined interfaces, which should not be changed as a rule, and often can not be changed because they are from third parties. In addition, the adapter is used in the creation of reusable classes, if they are to work together with independent or unforeseeable classes.

UML diagram

The so-called " Gang of Four" ( Gang of Four ) describes two design stage. The first is the adapter with delegation ( the so-called object adapter ), the second of the adapter with Inheritance ( Class adapter).

Adapter with delegation ( object adapter )

Here, the adapter has an association with the class to be adapted and forwards the requests by Delegation.

The advantage is that the adapter and the underlying service can be exchanged; for the entire interface used must be implemented, even if only a part of the implementation is to be adjusted.

Object adapter also known as an envelope or wrapper class class. Not only other classes can be encapsulated, but also primitive data types or procedural programming libraries.

Cover classes for primitive data types

An application for cover classes in object -oriented programming languages ​​is to provide classes for primitive data types available to simplify handling and to provide additional functions. There are, for example, in the Java programming language for the type int, the Integer class, the class character for char or float for the Float class (as well as short, long, Boolean, and Double). This case classes allow the object- oriented approach to primitive data types, for example, in order to integrate them into a reflection concept.

To facilitate the use of sheath classes 5, the so-called boxing Autoboxing or introduced in Java. This technique allows the use of cover classes in the usual form of primitive data types. Instead of object creation using Integer i = new Integer (100 ) simply can the spelling Integer i = 100 used. Also, the reference variable can be used i as if it were an ordinary int variable. The simple notation and readability at the expense of a significantly poorer execution speed.

Cover classes for procedural libraries

Another important use is the adaptation of a procedural library an object-oriented software system. Here, the function-oriented library services in one or more objects are encapsulated. This application form is often found as a design pattern facade.

Adapter with Inheritance ( Class adapter)

A class adapter is realized by means of multiple inheritance. For one, it inherits the implementation of the class to be adapted. On the other hand -to-implement interface. The call is then made by self- delegation.

A class adapter can then be put to good use when the programming language ( such as C ) supports the necessary language features ( multiple inheritance, private inheritance ). Programming without private and multiple inheritance are rather unsuitable for this type of adapter. The attempt to circumvent this restriction on the combination of class inheritance and interface implementation, means that the adapter class provides all the methods available to their clients. While the construct may be used as an adapter, but is not an adapter as defined in GoF Buchs, which transfers an interface to another.

Pros and Cons

The advantages of a class adapter are that it perfectly adapts to a target class, and can thus only override the behavior of the target class. The object adapter can adapt subclasses.

The disadvantage is that a class adapter can not be used for automatic adjustment of subclasses.

Actors

The service provides for reuse services with a defined interface. The client uses services via different interfaces and draws on adapted interfaces. The goal defines the interface that the client can use. The adapter adapts the interface of the service to the interface to the client.

Examples

Generally

The access of the elements of a graphical user interface to the underlying model can be controlled via an adapter with delegation. For example, a checkbox display both a buffered Boolean value as well as the immediate result of a condition. This pattern is used extensively among other things, VisualWorks Smalltalk.

Class adapter

/ / C code example   / * The interface, which is to implement the adapter * / Used class Interface { public:    Used interface ();    virtual void operational () const; };   / * The deployment, which should use the adapter * / class Adaptee { public:    Adaptee ();    void adaptedOperation () const; };   / * The actual adapter class * / adapter class: public interface Used, private Adaptee { public:    Adapter ();    operational void () const; };   / * Implementation of the adapter * / void Adapter :: operational () const {    Adaptee :: adaptedOperation (); } A concrete example in C

We bought two ( commercial ) libraries (whose implementation we do not see and can not change). The first is a library for computational geometry. It contains algorithms that operate on geometric objects such as circles, lines, and planes, for example, an algorithm that tests whether two circles intersect. The second is a GUI library, which is also known objects such as circles and lines and is able to draw on the screen.

Now we want to determine with the help of the first library, whether cut two circles that we exist as objects of the second library ( before we paint them on the screen).

Unfortunately, the interfaces of the two libraries are incompatible. They differ not only in term of classes ( circle vs. Circle), but also in the name and semantics of the methods ( getMittelpunkt ( ) vs. GetX () and getY ()).

The algorithms of geometry library work with only the public interface ( the interface ) of the geometric objects. A circle, for example, must be able to give only information about its radius and its center. He is represented by an abstract class using the appropriate methods getRadius () and getMittelpunkt (). He has no member variables for the radius and center, because it could also be defined differently by two points on the boundary, which are diametrically opposed by three points on the boundary or implicitly as the solution set of the equation. Thus, the algorithms are independent of the actual representation of geometrical objects. Points, however, are in the library ( concrete ) is implemented as a structure.

/ / Library for computational geometry   struct point {    double _x, _y; / / For simplicity public    Point (double x, double y ): _x (x ), _y (y ) {} };   class Circle {/ / abstract class, only the interface public:    virtual double getRadius () const = 0;    virtual point getMittelpunkt () const = 0; };   / / The implementation of this function is based purely on the / / Interface, not on concrete realizations: bool intersects circle circle (const circle & k1, const Circle & k2) {    double abstandDerKreise = distance ( k1.getMittelpunkt () k2.getMittelpunkt ());    return abstandDerKreise <= ( k1.getRadius () k2.getRadius ()); } The graphical objects in the GUI library can draw on the screen. A Circle is internally represented by three floating-point numbers, two for the center coordinates and one for the radius. It can give information about its geometry ( getX (), etc.):

/ / GUI library   class GraphicalObject {    virtual void draw () = 0; / / Draw yourself on the screen };   class Circle: public GraphicalObject { private:    double _MX, _my; / / Center x and y    double _r; / / Radius public:    Circle (double x, double y, double r): _MX (x ), _my (y), _r (r ) {}    double getX () const {return _MX; }    double getY () const {return _my; }    double sep () const {return _r; }    void draw () { / * draw you with Bresenham algorithm * /} }; As we see, the interfaces of the two libraries are different. To order but can now use a Circle in one of the algorithms for circular, we write an adapter for Circle objects. Each adapter object contains a Circle to be adapted and implemented the interface of circle:

/ / Circle adapter to use a circle as a circle in the / / Geometry library   Circle class Adapter: public Circle, Circle { private public:    Circle adapter (const Circle & c ), Circle ( c.getX () c.getY () c.getR ()) { }      / / Here Circle is adapted so that it fits on circle    double getRadius () const {return sep (); }    Point getMittelpunkt () const {return Point ( getX (), getY ()); } }; Now we can test two circle of the GUI library seen as a circle with the algorithm of the geometry library section:

Int main () {    / / We get from GUI library two Circles    Circle c1 = Circle (1.0, 0.0, 2.0);    Circle c2 = Circle ( 3.0, 0.0, 2.0);      / / They are stuck in a Circle Adapter    Circle adapter c1Adapter (c1 );    Circle adapter c2Adapter (c2 );      / / And use geometry library for testing on an average    if ( cut circles circle ( c1Adapter, c2Adapter )) {      ...    Else { }      ...    } } Related design patterns

Bridge and adapter are similar. However, the bridge is a deliberate design decision to separate an interface from its implementation, while the adapter any subsequent adjustment of an interface is to another.

Facade and adapter are a form of the envelope class. However, the facade conceals the functions of a library in whole or in part, while the adapter only changes the interface.

29055
de