Design Patterns 02 - Adapter mode

definition

Adapter design pattern, by definition is the role of the adapter becomes organized way of summary abstract code, existing code by adapting the adapter, in order to meet the requirements of the project to another class or interface. In other words, a class interface adapter (packaging / converting) into another interface clients (the caller) desired. Adapter design pattern has the following two forms:

  • Class Adapter mode (inherited adapter)
  • Object Adapter mode (using a delegate adapter)

Issues into

We used laptop accessories have one adapter, is responsible for 220Vthe alternating current is converted into 12VDC power for laptops, it exists role is to 220Valternating current is converted into 12Vdirect current. So it is the adapter, 220VAC power adapter is to be the object, and 12Vthe direct current is converted target object, the caller laptop is the target object.

Application Adapter design patterns in the JDK source code

Learn adapter design pattern, of course, from the need JDKto find traces of it in the JDKsource code, where the use of the adapter design pattern of many, such as the most common IOconversion flow and collections and so on. Next we together from source code to analyze how to use the adapter design pattern is up.
Together we read the java.io.InputStreamReader(InputStream)part of the source code:

InputStreamReaderThe role of the byte stream into a character stream, the conversion between them is a bridge (adapter), that is to say, InputStreamReaderis the adapter, is responsible for InputStreamconvert Reader, so that you can use Readermethods to perform the operation.

package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import sun.nio.cs.StreamDecoder;

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;
    
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }
    
    public String getEncoding() {
        return sd.getEncoding();
    }

    public int read() throws IOException {
        return sd.read();
    }

    public int read(char cbuf[], int offset, int length) throws IOException {
        return sd.read(cbuf, offset, length);
    }

    public boolean ready() throws IOException {
        return sd.ready();
    }

    public void close() throws IOException {
        sd.close();
    }
}

The above code is the result of the deletion of part of the code, delete the comments in the source code as well as several construction methods, read from the source point of view, this form of adapter design pattern uses " 对象适配器模式" As for what is " 对象适配器模式," we will in the latter study in the introduction, readers can temporarily disregard what is' 对象适配器模式. "

Manual mode adapter is designed to achieve

Next, we will implement two adapter design manual mode, with a simple code to illustrate how the adapter design pattern is up and running.

Former child have played QQthe game, sometimes need to recharge Qcoins, use Qcoins to purchase items in the game, this scenario can be fully applicable adapter design mode, in this scenario, using the Qmoney to buy game items are our needs, but also is our goal ( Target), but the status quo is that we now have the RMB, the yuan is adapted object ( Adaptee), the RMB can not directly buy props in the game, it needs to be converted into the Qcurrency can be traded, so we also need an adapter ( Adapter), is responsible for converting the yuan into Qdollars.
According to the above text, we can be summarized into a table, you can easily clear the relationship between geography:

Roles Actor effect
Target Props to buy the game interface There recharge Q coins interfaces have to use Q coins prepaid game props Interface
Adapter Q currency recharge device RMB will be converted into Q coins and complete recharge
Adaptee Renminbi Adapted, the object is converted

According to the above relationship, we were to create a class or interface corresponding to each role. Here we simulate the use of the yuan prepaid Qcurrency, using the Qcase of currency to buy game items, assuming a unit of the yuan can recharge 10two Qcoins, each Qcoin can be a game props.

Code Example 1: Class Adapter design pattern (using inheritance adapter)
  • Target

Our goal is to have an interface, this interface can purchase game items, but need to use the Qmoney to make a purchase. In the adapter design pattern, it is the ultimate goal we needed.

package cn.itlemon.design.pattern.chapter02.adapter.example3;

/**
 * @author jiangpingping
 * @date 2018/9/6 下午7:43
 */
public interface TargetInterface {

    /**
     * 购买qCoinCount个游戏道具
     */
    void buyGameProps();

}
  • Adaptee

Now is the status quo of RMB on hand, so the need for a Qcurrency recharge device, the value of the RMB into the same Qcurrency. Adapter design pattern in which the yuan is needed to be adapted to the object because it can not be directly used to purchase game items, but that it must pass before it can recharge Qcurrency, in order to meet the requirements.

package cn.itlemon.design.pattern.chapter02.adapter.example3;

/**
 * 人民币
 *
 * @author jiangpingping
 * @date 2018/9/6 下午7:45
 */
public class Rmb {

    private int count;

    public Rmb(int count) {
        this.count = count;
    }

    public int getCount() {
        return this.count;
    }

}
  • Adapter

So we need a Qcurrency recharge device, the RMB into Qdollars, and then also have to buy the game props function. In the adapter design pattern, the Qcurrency recharge is that we need an adapter.

package cn.itlemon.design.pattern.chapter02.adapter.example3;

/**
 * Q币充值器
 *
 * @author jiangpingping
 * @date 2018/9/6 下午7:31
 */
public class QCoinRechargeableDevice extends Rmb implements TargetInterface {

    private int qCoinCount;

    public QCoinRechargeableDevice(int rmbCount) {
        super(rmbCount);
        this.qCoinCount = getCount() * 10;
    }

    @Override
    public void buyGameProps() {
        System.out.println("一共购买了" + qCoinCount + "个道具");
    }
}
  • Main

Here to write a Mainmethod to validate our design above adapter design pattern, the main code is as follows:

package cn.itlemon.design.pattern.chapter02.adapter.example3;

/**
 * @author jiangpingping
 * @date 2018/9/6 下午9:26
 */
public class Main {

    public static void main(String[] args) {
        TargetInterface qCoinRechargeableDevice = new QCoinRechargeableDevice(10);
        qCoinRechargeableDevice.buyGameProps();
    }
}

Here, we have to Qrecharge currency recharge device 10units of the RMB, you can complete the purchase 100game props change. Originally RMB can not be directly used to purchase game items, after using the adapter design pattern, you can purchase game items to complete our needs.

Use inherited adapter UML class diagram

Write pictures described here
Use inherited adapters have a feature that is Adapterinherited Adaptee, and realized Targetthat this is the relationship between the three.

Code Example 2: Object Adapter design pattern (using the delegate adapter)

Here only the code posted, for each class described in the above have been described.

  • Target
package cn.itlemon.design.pattern.chapter02.adapter.example4;

/**
 * @author jiangpingping
 * @date 2018/9/10 下午9:16
 */
public abstract class TargetInterface {

    /**
     * 购买qCoinCount个游戏道具
     */
    public abstract void buyGameProps();
}
  • Adaptee
package cn.itlemon.design.pattern.chapter02.adapter.example4;

/**
 * 人民币
 *
 * @author jiangpingping
 * @date 2018/9/6 下午7:45
 */
public class Rmb {

    private int count;

    public Rmb(int count) {
        this.count = count;
    }

    public int getCount() {
        return this.count;
    }

}
  • Adapter
package cn.itlemon.design.pattern.chapter02.adapter.example4;

/**
 * @author jiangpingping
 * @date 2018/9/10 下午9:18
 */
public class QCoinRechargeableDevice extends TargetInterface {

    private Rmb rmb;

    public QCoinRechargeableDevice(Rmb rmb) {
        this.rmb = rmb;
    }

    @Override
    public void buyGameProps() {
        System.out.println("一共购买了" + rmb.getCount() * 10 + "个道具");
    }
}
  • Main
package cn.itlemon.design.pattern.chapter02.adapter.example4;

/**
 * @author jiangpingping
 * @date 2018/9/10 下午9:16
 */
public class Main {

    public static void main(String[] args) {
        TargetInterface qCoinRechargeableDevice = new QCoinRechargeableDevice(new Rmb(10));
        qCoinRechargeableDevice.buyGameProps();
    }
}
Use delegate (object) adapter UML class diagram

Write pictures described here
Use commissioned adapters have a feature that is Adapterowned Adapteeand inherited Targetabstract class, which is the relationship between the three.

On the adapter mode key role

One adapter design pattern is a more common design patterns, now on the adapter design pattern analysis roles.

  • Target(对象)
    该角色负责定义最终的需求,也就是使用适配器模式之后的最终效果。在本次示例中,TargetInterface就是扮演了这个Target角色。

  • Adaptee(被适配)
    该角色定义的是原始的功能,它也许无法直接被利用,但是又不能随意更改,所以它就需要被适配,使得在不修改原始代码的情况下能激活Target的功能。在本次示例中,Rmb扮演了这个角色。

  • Adapter(适配)
    该角色是适配器设计模式的核心角色,他负责适配AdapteeTarget,使得Adaptee来满足Target的需求。在本次示例中,QCoinRechargeableDevice扮演了这个角色。

  • Client(请求者)
    该角色负责调用Target的方法来进行一系列的逻辑处理。在本次示例中,Main类扮演了这个角色。

适配器设计模式UML类图

分析完适配器设计模式的重要角色,当然也得理清适配器设计模式的UML类图。

  • 使用继承的适配器设计模式类图

Write pictures described here

  • 使用委托的适配器设计模式类图

Write pictures described here

为什么要使用适配器设计模式

我们往往有这种思想,要使用什么类的方法,直接使用不就OK了,或者稍微修改一下已有的代码不就可以使用了吗?其实这种思想是不正确的,因为在现有类的基础下,很多类的方法都经过了严格的测试,贸然地去修改他容易造成意外情况的发生,我们使用适配器设计模式,往往无需修改现有的代码,直接在现有的代码的基础上创建新的代码,这样即使出了错误,我们也能很快从我们新写的代码中找出端倪。使用适配器设计模式,也是对现有代码的一种重复利用。

更多干货分享,欢迎关注我的微信公众号:爪哇论剑(微信号:itlemon)
Here Insert Picture Description

Published 73 original articles · won praise 84 · views 470 000 +

Guess you like

Origin blog.csdn.net/Lammonpeter/article/details/82353178