Java 设计模式之适配器模式

适配器模式(Adapter Pattern)是不兼容接口之间的桥梁,可以使一个类加入独立的或不兼容的接口功能。比如计算机通过适配器读取之前无法读取的TF卡;下面用Java模拟这一过程的实现;

计算机本身可以读取SD卡,通过适配器读取TF卡。

类继承/实现关系简图

具体实现

  1. 先创建个SD卡接口

    1
    2
    3
    4
    5
    6
    7
    public interface SdCard {
    /**读sd卡*/
    String readSdCard();

    /** 写sd卡*/
    int writeSdCard(String msg);
    }
  2. 创建SD卡接口的实现类,模拟SD卡功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class SdCardImpl implements SdCard {
    @Override
    public String readSdCard() {
    return "欢迎使用Sd卡";
    }

    @Override
    public int writeSdCard(String msg) {
    System.out.println("SD写入信息:"+msg);
    return 1;
    }
    }
  3. 创建个计算机接口

    1
    2
    3
    4
    5
    6
    7
    public interface Computer {
    /**读取SD卡*/
    String readSdCard(SdCard sdCard);

    /**写入sd卡*/
    void writeSdCard(SdCard sdCard,String msg);
    }
  4. 创建计算机接口的实现类,模拟计算机对SD卡的读写操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class MacComputer implements Computer {
    @Override
    public String readSdCard(SdCard sdCard) {
    if (sdCard == null) {
    throw new NullPointerException("未放入sd卡!");
    }
    return sdCard.readSdCard();
    }

    @Override
    public void writeSdCard(SdCard sdCard, String msg) {
    if (sdCard == null || msg.isEmpty()) {
    throw new NullPointerException("写入sd卡失败!");
    }
    if (sdCard.writeSdCard(msg)==1) {
    System.out.println("写入完成!");
    }
    }
    }
  5. 现在创建一个测试类,模拟计算机读取SD卡

    1
    2
    3
    4
    5
    6
    7
    8
    public class Test {
    public static void main(String[] args) {
    Computer macComputer = new MacComputer();
    SdCard sdCard = new SdCardImpl();
    System.out.println("读出信息:"+macComputer.readSdCard(sdCard));
    macComputer.writeSdCard(sdCard,"sd写入测试。。。");
    }
    }

    执行结果

计算机已经读取SD卡成功,下面在不改变计算机读取SD卡接口的前提下,使用适配器实现读取TF卡;

  1. 创建TF卡接口

    1
    2
    3
    4
    5
    6
    7
    public interface TfCard {
    /** 读Tf卡 */
    String readTfCard();

    /** 写入Tf卡*/
    int writeTfCard(String msg);
    }
  2. 创建TF卡接口的实现类,同样模拟TF卡功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class TfCardImpl implements TfCard {
    @Override
    public String readTfCard() {
    return "欢迎使用TF卡";
    }

    @Override
    public int writeTfCard(String msg) {
    System.out.println("TF写入信息:"+msg);
    return 1;
    }
    }
  3. 创建SD适配TF的适配器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class SdAdapterTf implements SdCard {
    /**将TfCard作为属性引入适配器*/
    private TfCard tfCard;

    public SdAdapterTf(TfCard tfCard) {
    this.tfCard = tfCard;
    }

    @Override
    public String readSdCard() {
    System.out.println("适配器读TF卡");
    return tfCard.readTfCard();
    }

    @Override
    public int writeSdCard(String msg) {
    System.out.println("适配器写TF卡");
    tfCard.writeTfCard(msg);
    return 1;
    }
    }
  4. 测试,模拟计算机读取TF卡

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Test {
    public static void main(String[] args) {
    Computer macComputer = new MacComputer();
    SdCard sdCard = new SdCardImpl();
    System.out.println("读出信息:"+macComputer.readSdCard(sdCard));
    macComputer.writeSdCard(sdCard,"sd写入测试。。。");
    System.out.println("================================");
    TfCard tfCard = new TfCardImpl();
    SdAdapterTf sdAdapterTf = new SdAdapterTf(tfCard);
    System.out.println("读出信息:"+macComputer.readSdCard(sdAdapterTf));
    macComputer.writeSdCard(sdAdapterTf,"Tf写入测试");
    }
    }

    执行结果

小结

因为不能改变computer类的SDCard接口,所以适配器需要实现SDCard接口,保证适配器能“插入”computer,而将TFCard作为私有属性引入适配器,实现了将TFCard插入适配器,通过以上过程,TF卡成功被计算机读取;

适配器模式是Java多态的完美体现,不仅拓展了功能,还对原有代码无侵入性。但是,适配器并不适合在程序设计时应用,因为当适配器变多后,对接口的调用不再清晰,如对接口A的调用,可能在A内调用了B接口,这将导致接口混乱。更好的使用情况是在系统正常运行时,为了兼容新接口而有机的使用。