1 基础概念

1、定义

  • 将一个类的接口转换成客户希望的另外一个接口。
  • Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

2、角色分析

  • 目标接口:客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口。
  • 需要适配的类:需要适配的类或适配者类。
  • 适配器:通过包装一个需要适配的对象,把原接口转换成目标对象!

3、优点

  • 一个对象适配器可以把多个不同的适配者适配到同一个目标。
  • 可以适配一个适配者的子类,由于适配器和适配者之间是关联关系,根据“里氏替换原则”,适配者的子类也可以通过该适配器进行适配。

4、缺点

  • 对于Java、C#等不支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配者。
  • 在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定的局限性。

5、使用场景

  • 系统需要使用一些现有的类,而这些类的接口(如方法名)不符号系统的需要,甚至没有这些类的源代码。
  • 想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

2 代码

1、继承(类适配器,单继承)

图片说明

  • Computer

    package adapter;
    
    // 电脑(插不上网线)
    public class Computer {
        // 电脑需要连接上转换器才可以上网
        public void net(NetToUsb adapter) {
            // 上网的具体实现
            adapter.handleRequest();
        }
    }
  • Adaptee

    package adapter;
    
    // 被适配的类:网线
    public class Adaptee {
        public void request() {
            System.out.println("连接网线上网");
        }
    }
  • NetToUsb

    package adapter;
    
    // 接口转换器的抽象实现
    public interface NetToUsb {
        // 作用:处理请求
        public void handleRequest();
    }
  • Adapter

    package adapter;
    
    // 真正的适配器:连接USB、网线
    public class Adapter extends Adaptee implements NetToUsb {
        @Override
        public void handleRequest() {
            super.request();    // 可以上网了
        }
    }

2、组合(对象适配器:常用)

图片说明

  • Adapter2

    package adapter;
    
    public class Adapter2 implements NetToUsb {
        private Adaptee adaptee;
    
        public Adapter2(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        @Override
        public void handleRequest() {
            adaptee.request();
        }
    }

3、测试

  • MyTest

    package adapter;
    
    import org.junit.Test;
    
    public class MyTest {
        @Test
        public void test() {
            // 电脑
            Computer computer = new Computer();
            // 适配器
            Adapter adapter = new Adapter();
            // 网线
            Adaptee adaptee = new Adaptee();
            computer.net(adapter);
            // 升级版
            Computer computer1 = new Computer();
            Adaptee adaptee1 = new Adaptee();
            Adapter2 adapter2 = new Adapter2(adaptee1);
            computer1.net(adapter2);
        }
    }