适配器模式之3种实现方式

目录

    • (一) 适配器模式概述
    • (二) 类适配器模式
    • (三) 对象适配器模式
    • (四) 接口(缺省)适配器模式

(一) 适配器模式概述

适配器模式(Adapter Pattern): 将某个类的接口转换成客户端期望的另一个接口表示, 主要目的是兼容性, 让原来不兼容的两个接口协同工作, 其别名为包装器(Wrapper).

适配器模式属于结构型模式, 主要分为三类:

  • 类适配器模式
  • 对象适配器模式
  • 接口适配器模式

适配器模式的工作原理

  • 适配器模式将一个类的接口转换成另一种接口, 让原本接口不兼容的类可以兼容
  • 从用户的角度看不到被适配者(Adaptee), 是解耦的
  • 用户调用适配器转化出来的目标接口方法, 适配器再调用被适配者的相关接口, 如图
    适配器模式之3种实现方式_第1张图片

(二) 类适配器模式

类适配器模式(Class Adapter Pattern): Adapter适配器类, 继承 Adaptee被适配器类, 实现 Target目标类的接口, 完成适配.

举例: 在生活中手机充电器, 需要将家用220V的交流电 转换为 5V的直流电后, 才能对手机充电. 在这个案例中

  • 手机充电器 相当于 Adapter适配器
  • 220V的交流电 相当于 Adaptee 被适配者
  • 5V的直流电 相当于 Target目标

适配器模式之3种实现方式_第2张图片

Adaptee被适配器类: 220V电压类

class Voltage220VAdaptee {

    public int output220V() {
        System.out.println("家用输出220V电压");
        return 220;
    }
}

Target目标接口: 输出5V电压的抽象方法

interface Voltage5VTarget {
    int output5V();
}

Adapter适配器类: 将220V电压 转换成 5V电压

class VoltageAdapter extends Voltage220VAdaptee implements Voltage5VTarget {

    @Override
    public int output5V() {
        int v = super.output220V();
        v = v / 44;
        System.out.println("VoltageAdapter适配类: 将220V电压 转换成 5V电压");
        return v;
    }
}

手机实体类

class Phone {
    public void charge(Voltage5VTarget voltage5VTarget) {
        System.out.println("手机充电压为: " + voltage5VTarget.output5V() + "V");
    }
}

测试:

public class ClassAdapterPattern {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.charge(new VoltageAdapter());
    }
}

在这里插入图片描述
类适配器模式注意事项和细节

  • Java是单继承机制, Adapter类适配器需要继承 Adptee被适配者类, 导致 Target目标必须是接口, 有一定的局限性 (继承, 破坏了类的封装性, 父类对于子类来说是透明的, 且耦合度高)
  • 由于继承 Adptee被适配者类, 所以可以根据需求重写 Adptee被适配者类的方法, 是的Adapter的灵活性增强了

(三) 对象适配器模式

对象适配器模式(Object Adapter Pattern): 基本思路与类适配器模式相同, 只是将 Adapter适配器类修改, 不是继承 Adaptee被适配者, 而是拥有 Adaptee类的实例, 以解决兼容性的问题.

根据 “合成复用原则”, 在系统中尽量使用关联关系来替代继承关系.

适配器模式之3种实现方式_第3张图片

修改VoltageAdapter适配器类, 将继承 Voltage220VAdaptee类, 修改成拥有 Voltage220VAdaptee类的成员属性

class VoltageAdapter implements Voltage5VTarget {

    private Voltage220VAdaptee voltage220VAdaptee;

    public VoltageAdapter(Voltage220VAdaptee voltage220VAdaptee) {
        this.voltage220VAdaptee = voltage220VAdaptee;
    }

    @Override
    public int output5V() {
        int v = voltage220VAdaptee.output220V();
        v = v / 44;
        System.out.println("VoltageAdapter适配类: 将220V电压 转换成 5V电压");
        return v;
    }
}

...

public class ObjectAdapterPattern {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.charge(new VoltageAdapter(new Voltage220VAdaptee()));
    }
}

在这里插入图片描述

对象适配器模式, 根据合成复用原则, 使用组合替代继承, 解决了类适配器必须继承 Adaptee被适配者, 同时也不在要求 Target目标必须是接口, 可以为抽象类


(四) 接口(缺省)适配器模式

接口适配器模式(Default Adapter Pattren): 又称之为 缺省适配器模式. 当不需要实现接口提供的所有方法时, 可先设计一个抽象类(AbsAdapter)实现接口, 并为该接口中每个方法提供一个默认实现(空方法). 那么使用抽象类AbsAdapter时, 可有选择地覆盖父类的默写方法来实现需求. 适用于一个接口不想使用其所有的方法的情况

Interface1接口: 只想使用method1方法

interface Interface1 {

    void method1();

    void method2();

    void method3();

    void method4();

}

AbsAdapter 抽象类实现接口, 并为该接口中每个方法提供一个默认实现(空方法)

abstract class AbsAdapter implements Interface1 {

    // 默认实现, 空方法
    @Override
    public void method1() {
    }

    @Override
    public void method2() {
    }

    @Override
    public void method3() {
    }

    @Override
    public void method4() {
    }

}

测试: 通过匿名函数使用抽象类AbsAdapter, 覆盖重写method1方法

public class DefaultAdapterPattern {
    public static void main(String[] args) {
        AbsAdapter absAdapter = new AbsAdapter() {
            @Override
            public void method1() {
                System.out.println("只是用method1方法");
            }
        };

        absAdapter.method1();
    }
}

在这里插入图片描述

你可能感兴趣的:(设计模式,java,设计模式)