适配器模式(Adapter Pattern)

简介: 适配器模式(Adapter Pattern)

现实生活中的适配器例子

image.png

image.png

介绍

1.1 定义

适配器模式,即定义一个包装类,用于包装不兼容接口的对象

包装类 = 适配器Adapter;     被包装对象 = 适配者Adaptee = 被适配的类  

1.2 主要作用

把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。

适配器模式的形式分为:类的适配器模式和对象的适配器模式  

1.3 解决的问题

原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

工作原理

image.png

image.png

适配器模式


适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。也称包装器(Wrapper),属于结构型模式。适配器模式主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

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

简单来说,适配器模式就像个插头转换器,让不同标准的插头和插座可以一起使用,而插座就是原来的接口,插头是用户期望的接口。或者类比电源适配器,把原来的220V电压转换成5V电压等。

类适配器

顾名思义,通过适配器通过类来实现,以类来继承和实现接口的方式,来获取被适配类的信息并转换输出重写到适配接口。即Adapter类,通过继承src类,实现dst类接口,完成src->dst的适配。

image.png

package java设计模式.Adapter;
//被适配的类
public class Voltage220V {
    public int output220V(){
        int out=220;
        System.out.println("电压=" + out);
        return out;
    }
}
package java设计模式.Adapter;
//适配器类
public class VoltageAdapter extends Voltage220V implements IVoltage5V{

    @Override
    public int output5V() {
        //获取220V电压
        int srcv = output220V();
        int dstv =  srcv/ 44;  //转化为5v
        return dstv;
    }
}
package java设计模式.Adapter;
//适配接口
public interface IVoltage5V {
    public int output5V();
}
package java设计模式.Adapter;
//调用
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,不可充电");

        }
    }
}
public class Client {
    public static void main(String[] args) {
        System.out.println("===类适配器测试===");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}

image.png

优缺点:

有一定局限性。因为类适配器需要继承src类,而Java是单继承机制,所以要求dst必须是接口。
src类的方法在Adapter中都会暴露出来,耦合性高。
可以根据需求重写src类的方法,使得Adapter的灵活性增强了。

对象适配器模式

顾名思义,通过实例对象(构造器传递)来实现适配器,而不是再用继承,其余基本同类适配器。即:持有src类,实现dst类接口,完成src->dst的适配。
合成复用原则 聚合关系

image.png

package java设计模式.Adapter.对象适配器;
//适配器类
public class VoltageAdapter implements IVoltage5V{
    private Voltage220V voltage220V;
    //构造器
    public VoltageAdapter(Voltage220V voltage220V){
        this.voltage220V=voltage220V;
    }
    @Override
    public int output5V() {
        int dst=0;
        if(null!=voltage220V){
            int src=voltage220V.output220V(); //获取220v电压
            dst=src/44;
        }
        return dst;
    }
}
package java设计模式.Adapter.对象适配器;
//被适配的类(不变)
public class Voltage220V {
    public int output220V(){
        int src=220;
        System.out.println("电压="+src);
        return src;
    }
}
package java设计模式.Adapter.对象适配器;


//调用 不变
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,不可充电");

        }
    }
}
package java设计模式.Adapter.对象适配器;
//适配器接口
public interface IVoltage5V {
    public int output5V();
}
package java设计模式.Adapter.对象适配器;
public class Client {
    public static void main(String[] args) {
        System.out.println("===对象适配器===");
        Phone phone = new Phone();
       phone.charging(new VoltageAdapter(new Voltage220V()));

    }
}

image.png

接口适配器

继承那边可以解耦了,那能不能从接口这边解耦?

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

image.png image.png

image.png

image.png

image.png

package java设计模式.Adapter.interfaceadapter;

public interface Interface4 {
    public void m1();
    public void m2();
    public void m3();
    public void m4();
}
package java设计模式.Adapter.interfaceadapter;
//在AbsAdapter中我们将Interface4空实现
public abstract class AbsAdapter implements Interface4{
    @Override
    public void m1() {

    }

    @Override
    public void m2() {

    }

    @Override
    public void m3() {

    }

    @Override
    public void m4() {

    }
}
package java设计模式.Adapter.interfaceadapter;

public class Client {
    public static void main(String[] args) {
        //分配一个变量  匿名内部类
        AbsAdapter adapter=new AbsAdapter(){
            //只需要去覆盖我们需要使用接口方法
            @Override
            public void m1() {
                System.out.println("使用m1方法");
            }
        };
        adapter.m1();
    }
}
//被适配的类(不变)
public class Voltage220V {
    public int output220V() {
        int src = 220;
        System.out.println("电压=" + src);
        return src;
    }
}

//适配接口
public interface IVoltage5V {
    public int output5V();
    public void m2(); //接口里冗余不重要的方法
    public String m3();
}
//抽象适配器
public abstract class AbsAdapter extends Voltage220V implements IVoltage5V{
    @Override //以空方法实现接口所有方法
    public int output5V() {
        return 0;
    }
    @Override
    public void m2() {
    }
    @Override
    public String m3() {
        return null;
    }
}

//调用(不变)
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,不可充电");
        }
    }
}

//测试
public class Client {
    public static void main(String[] args) {
        System.out.println("===接口适配器===");
        AbsAdapter absAdapter = new AbsAdapter() { //匿名内部类的形式
            @Override //按需要重写接口方法
            public int output5V() {
                System.out.println("使用了output5V的方法");
                int srcV = output220V();
                int dstV = srcV / 44 ; //转成5v
                return dstV;
            }
        };
        Phone phone = new Phone();
        phone.charging(absAdapter);
    }
}

image.png

以上三种形式是根据src是以怎样的形式给到Adapter来命名的:

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

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

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

Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作,在实际开发中,实现起来不拘泥于我们讲解的三种经典形式。


相关文章
|
设计模式
设计模式8 - 适配器模式【Adapter Pattern】
设计模式8 - 适配器模式【Adapter Pattern】
47 0
|
2月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
设计模式
适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将现有的类或接口转换为客户端所期望的另一个接口,以解决不兼容的问题。
78 2
|
设计模式 算法 Java
建造者模式(Builder Pattern)
建造者模式(Builder Pattern)是一种创建型设计模式,它可以将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
98 1
|
Java 程序员 API
结构型模式 - 适配器模式(Adapter Pattern)
结构型模式 - 适配器模式(Adapter Pattern)
|
设计模式 Java 程序员
适配器模式(Adapter Pattern)
适配器模式是一种结构型设计模式, 它能将接口转换为客户期望的另一个接口,也就是说它能使接口不兼容的对象能够相互合作。
127 0
适配器模式(Adapter Pattern)
|
设计模式 C#
【愚公系列】2021年12月 二十三种设计模式(六)-适配器模式(Adapter Pattern)
【愚公系列】2021年12月 二十三种设计模式(六)-适配器模式(Adapter Pattern)
122 0
【愚公系列】2021年12月 二十三种设计模式(六)-适配器模式(Adapter Pattern)
|
Java C#
使用C# (.NET Core) 实现适配器模式 (Adapter Pattern) 和外观模式 (Facade Pattern)
本文的概念内容来自深入浅出设计模式一书 现实世界中的适配器(模式) 我带着一个国标插头的笔记本电脑, 来到欧洲, 想插入到欧洲标准的墙壁插座里面, 就需要用中间这个电源适配器. 面向对象的适配器 你有个老系统, 现在来了个新供应商的类, 但是它们的接口不同, 如何使用这个新供应商的类呢? 首先, 我们不想修改现有代码, 你也不能修改供应商的代码.
1763 0