设计模式——适配器模式(附代码示例)

一. 适配器模式

1. 概念

        适配器模式(Adapter Rattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。类比,U盘插个转换头可用与手机type-c接口相连接;或者是使用多功能转换插头,实现三孔插头与两孔插座相连。

2. 工作原理

        适配器模式将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容。从用户的角度看不到被适配者,是解耦的;用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法;用户收到反馈结果,感觉只是和目标接口交互。

3. 分类

        适配器模式属于结构型模式,主要分为三类:类适配器模式、对象适配器模式、接口适配器模式。

二. 类适配器模式

1. 概念

        Adapter类,通过继承src类,实现dst类接口,完成src->dst的适配。

        缺点:Java是单继承机制,所以类适配器需要继承src类;要求dst必须是接口,有一定局限性;src类的方法在Adapter中都会暴露出来,也增加了使用的成本。        

        优点:由于其继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强了。

2. 类图

        以充电器转换电压为例

设计模式——适配器模式(附代码示例)_第1张图片 3. 代码示例

        Voltage220V类,表示被适配类,输出220v电压

//被适配类
public class Voltage220V {
    //输出220V的电压
    public int output220V(){
        int src = 220;
        System.out.println("电压="+src+"伏");
        return src;
    }
}

        IVoltage5V接口,表示适配接口,抽象输出5v的方法

//适配接口
public interface IVoltage5V {
    public int output5V();
}

         VoltageAdapter类,表示适配器类,继承被适配类,又实现适配接口,实现220v->5v转换

public class VoltageAdapter extends Voltage220V implements IVoltage5V{
    @Override
    public int output5V() {
        int srcV = output220V();//获取220v
        int dstV = srcV / 44;//转成5v
        return dstV;
    }
}

         Phone类,实现充电方法

public class Phone {
    //充电
    public void charging(IVoltage5V iVoltage5V){
        if(iVoltage5V.output5V()==5){
            System.out.println("电压为5v,可以充电");
        }else if(iVoltage5V.output5V()>5){
            System.out.println("电压大于5v,无法充电");
        }
    }
}

         Client类,客户端

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

输出结果 

设计模式——适配器模式(附代码示例)_第2张图片

三. 对象适配器模式

1. 概念

        基本思路和类的适配器模式相同,只是将Adapter类作修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。即:持有src类,实现dst类接口,完成src->dst的适配。根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系。对象适配器模式是适配器模式常用的一种。

2. 类图

         仍以充电器转换电压为例,只需改变适配器类和客户端,其他不变

 设计模式——适配器模式(附代码示例)_第3张图片 

3.代码示例        

         Voltage220V类,表示被适配类,输出220v电压

//被适配类
public class Voltage220V {
    //输出220V的电压
    public int output220V(){
        int src = 220;
        System.out.println("电压="+src+"伏");
        return src;
    }
}

        IVoltage5V接口,表示适配接口,抽象输出5v的方法

//适配接口
public interface IVoltage5V {
    public int output5V();
}

        VoltageAdapter类,表示适配器类,实现适配接口,通过聚合关系持有Voltage220V类而不再是继承,实现220v->5v转换

public class VoltageAdapter implements IVoltage5V {
    private Voltage220V voltage220V;

    //根据构造器,传入一个Voltage220V,聚合关系
    public VoltageAdapter(Voltage220V voltage220V) {
        this.voltage220V = voltage220V;
    }

    @Override
    public int output5V() {
        int dstV = 0;
        if (null != voltage220V) {
            int srcV = voltage220V.output220V();//获取220v
            dstV = srcV / 44;//转成5v
        }
        return dstV;
    }
}

         Phone类,实现充电方法

public class Phone {
    //充电
    public void charging(IVoltage5V iVoltage5V){
        if(iVoltage5V.output5V()==5){
            System.out.println("电压为5v,可以充电");
        }else if(iVoltage5V.output5V()>5){
            System.out.println("电压大于5v,无法充电");
        }
    }
}

         Client类,客户端

public class Client {
    public static void main(String[] args) {
        System.out.println("对象适配器模式");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter(new Voltage220V()));
    }
}

输出结果 

设计模式——适配器模式(附代码示例)_第4张图片

四. 接口适配器模式 

1. 概念

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

2. 类图

设计模式——适配器模式(附代码示例)_第5张图片

3.代码示例

        接口Interface4,表示提供4个方法 

public interface Interface4 {
    public void m1();
    public void m2();
    public void m3();
    public void m4();
}

        AbsAdapter抽象类,实现接口,并使接口每个方法默认空实现 

public abstract class AbsAdapter implements Interface4{
    //默认实现
    @Override
    public void m1() {

    }

    @Override
    public void m2() {

    }

    @Override
    public void m3() {

    }

    @Override
    public void m4() {

    }
}

         Client类,通过匿名内部类的方式,有选择地覆盖父类的某些方法来实现需求

public class Client {
    public static void main(String[] args) {
        AbsAdapter absAdapter = new AbsAdapter() {
            @Override
            public void m1() {
                System.out.println("只想使用m1的方法,只需覆盖m1的方法");
            }
        };
        absAdapter.m1();
    }
}

输出结果

设计模式——适配器模式(附代码示例)_第6张图片 

五. 总结 

        类适配器: 以类给到,在Adapter里,就是将src当做类,继承

        对象适配器: 以对象给到,在Adapter里,将src作为一个对象,持有

        接口适配器: 以接口给到,在Adapter里,将src作为一个接口,实现

        Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。

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