设计模式-适配器模式

适配器模式-简介

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型设计模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或者不兼容的接口功能。
适配器模式分为以下两类:

  • 类适配器模式(继承):耦合度较高
  • 对象适配器模式(聚合–推荐):耦合度较低

举个例子:
在生活中,我们经常给手机充电,通常来说我们的手机充电头是两头插座,而某些国外的地区,墙上的插口只有三头插口,这个时候,手机的充电头两头插口和墙上的三头插口就不兼容了,这个时候我们可以使用电源适配器,电源适配器一端连接三头插口,一段连接我们的手机充电头,这样我们就实现了充电功能。
设计模式-适配器模式_第1张图片

为什么需要适配器模式?

将一个类的接口转换成客户所需要的另外一种接口。适配器使得原本由于不兼容而不能一起工作的哪些类可以一起工作,遵循了“开闭原则”。

适配器模式的结构组成

我们想象一下手机耳机的场景,有一根3.5mm接口的耳机,但是手机上之后Type-C的接口,以及一根TypeC耳机转接头。

  • 目标接口(Target):当前业务所期待的接口,这里是TypeC接口。
  • 适配者类(Adaptee):它是被访问的和适配的现存组件库中的接口,这里是 3.5mm 耳机接口。
  • 适配器类(Adapter):它是一个转换器,通过继承或者引用适配者对象,把适配者接口转换成目标接口,让客户按照目标接口的格式访问适配者,这里指的是 TypeC耳机转接头。

代码示例

现在有一台电脑只能读取SD卡,而要读取TF卡中的内容就需要使用适配器模式。

类适配器模式

适配器通过继承原接口实现新接口的方法实现适配。
设计模式-适配器模式_第2张图片

//SD卡的接口
public interface SDCard {
    //读取SD卡方法
    String readSD();
    //写入SD卡功能
    void writeSD(String msg);
}

//SD卡实现类
public class SDCardImpl implements SDCard {
    public String readSD() {
        String msg = "sd card read a msg :hello word SD";
        return msg;
    }

    public void writeSD(String msg) {
        System.out.println("sd card write msg : " + msg);
    }
}

//电脑类
public class Computer {

    public String readSD(SDCard sdCard) {
        if(sdCard == null) {
            throw new NullPointerException("sd card null");
        }
        return sdCard.readSD();
    }
}

//TF卡接口
public interface TFCard {
    //读取TF卡方法
    String readTF();
    //写入TF卡功能
    void writeTF(String msg);
}

//TF卡实现类
public class TFCardImpl implements TFCard {

    public String readTF() {
        String msg ="tf card read msg : hello word tf card";
        return msg;
    }

    public void writeTF(String msg) {
        System.out.println("tf card write a msg : " + msg);
    }
}

//定义适配器类(SD兼容TF)
public class SDAdapterTF extends TFCardImpl implements SDCard {

    public String readSD() {
        System.out.println("adapter read tf card ");
        return readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        writeTF(msg);
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        SDAdapterTF adapter = new SDAdapterTF();
        System.out.println(computer.readSD(adapter));
    }
}

说明:
类适配器违背了“合成复用原则”。类适配器是客户类有一个接口规范的情况下可用,反之不可用。

对象适配器模式

适配器 实现新接口 并且 聚合原接口实现类 来完成适配。
设计模式-适配器模式_第3张图片

//创建适配器对象(SD兼容TF)
public class SDAdapterTF  implements SDCard {

    private TFCard tfCard;

    public SDAdapterTF(TFCard tfCard) {
        this.tfCard = tfCard;
    }

    public String readSD() {
        System.out.println("adapter read tf card ");
        return tfCard.readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        tfCard.writeTF(msg);
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        TFCard tfCard = new TFCardImpl();
        SDAdapterTF adapter = new SDAdapterTF(tfCard);
        System.out.println(computer.readSD(adapter));
    }
}

总结

优点
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。

缺点
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

你可能感兴趣的:(设计模式,设计模式,适配器模式)