Structural mode - Adapter mode (ADAPTER)

1. Definition and characteristics of the mode

Convert the interface of a class to another interface that the client wants. The Adapter pattern enables classes that would otherwise not work together due to incompatible interfaces to work together.

Adapter mode is divided into two types: class structure mode and object structure mode. The former has a higher degree of coupling between classes than the latter, and requires programmers to understand the internal structure of related components in the existing component library, so there are relatively few applications some.

The main advantages of this mode are as follows.

  • The client can transparently call the target interface through the adapter.
  • Existing classes are reused, and programmers can reuse existing adapter classes without modifying the original code.
  • Decoupling the target class and the adapter class solves the problem of inconsistent interfaces between the target class and the adapter class.
  • In many business scenarios, it conforms to the principle of opening and closing.


Its disadvantages are:

  • The adapter writing process needs to be fully considered in combination with business scenarios, which may increase the complexity of the system.
  • It increases the difficulty of code reading and reduces the readability of code. Excessive use of adapters will make the system code messy.

2. Aliases

Wrapper Wrapper

3. Motivation

Sometimes a toolbox class designed for reuse cannot be reused simply because its interface does not match that required by the specialized application domain.

4. Structure and implementation of the model

The class adapter mode can be implemented by multiple inheritance. For example,  C++  can define an adapter class to inherit both the business interface of the current system and the existing component interface in the existing component library; Java  does not support multiple inheritance, but it can define an adapter class to inherit Realize the business interface of the current system while inheriting the existing components in the existing component library.

The object adapter pattern can be used to introduce the components that have been implemented in the existing component library into the adapter class, and this class realizes the business interface of the current system at the same time. Now to introduce their basic structure.

1. Structure of the schema

Adapter pattern (Adapter) contains the following main roles.

  1. Target (Target) interface: the interface expected by the current system business, which can be an abstract class or an interface.
  2. Adaptee class: It is the component interface in the existing component library to be accessed and adapted.
  3. Adapter (Adapter) class: It is a converter that converts the adapter interface into the target interface by inheriting or referencing the adapter object, allowing customers to access the adapter in the format of the target interface.

There are two types of adapter patterns:

1. Object adapter pattern

-- In this adapter pattern, the adapter holds an instance of the class it wraps. In this case, the adapter invokes the physical entity of the wrapped object .

2. Class adapter pattern

-- In this adapter mode, the adapter inherits from the implemented class (generally multiple inheritance).

5. Sample code

5.1 Sample Class Adapter

class Target
{
public:
    // Methods
    virtual void Request(){};
};

// "Adaptee"
class Adaptee
{
public:
    // Methods
    void SpecificRequest()
    {
        cout<<"Called SpecificRequest()"<<endl;
    }
};

// "Adapter"
class Adapter : public Adaptee, public Target
{
public:
    // Implements ITarget interface
    void Request()
    {
        // Possibly do some data manipulation
        // and then call SpecificRequest
        this->SpecificRequest();
    }
};
int main()
{
    // Create adapter and place a request
    Target *t = new Adapter();
    t->Request();
    return 0;
}

5.2 Sample Object Adapter

// "ITarget"
class Target
{
public:
    // Methods
    virtual void Request(){};
};

// "Adaptee"
class Adaptee
{
public:
    // Methods
    void SpecificRequest()
    {
        cout<<"Called SpecificRequest()"<<endl;
    }
};

// "Adapter"
class Adapter : public Target
{
private:
    Adaptee *adaptee;
public:
    Adapter()
    {
        adaptee = new Adaptee();
    }
    // Implements ITarget interface
    void Request()
    {
        // Possibly do some data manipulation
        // and then call SpecificRequest
        adaptee->SpecificRequest();
    }
};
int main()
{
    // Create adapter and place a request
    Target *t = new Adapter();
    t->Request();
    return 0;
}

Guess you like

Origin blog.csdn.net/rukawashan/article/details/124549783