1. 适配器模式

##1.1 介绍

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

适配器模式就是在不改变原有结构和功能前提下,对类进行拓展(满足开闭原则),在继承原有类的基础上生成适配器类并实现对应接口,将现有类不能处理的请求,通过调用适配器类实现接口的方法进行完成

1.2 优缺点

优点

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

缺点

  • 过多地使用适配器,会让系统非常零乱,不易整体进行把握
  • 于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类

1.3 使用场景

  • 有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

1.4 注意事项

  • 适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

#2. 案例实现

现在某辆车需要播放CD功能,但是普通的CD播放器无法搭载在车上,因此我们使用了一个适配器类来实现CD接口,通过组合CDPlayer来实现播放功能。

public interface CD {
   
    void play();    
}

public class CDPlayer implements CD {
   

    @Override
    public void play() {
   
        System.out.println("演唱");
    }
}

public class CDPlayerCarAdapter implements CD {
   
    private CDPlayer cdPlayer;

    public CDPlayerCarAdapter(CDPlayer cdPlayer) {
   
        this.cdPlayer = cdPlayer;
    }

    @Override
    public void play() {
   
        System.out.println("适配器工作");
        cdPlayer.play();
    }
}

public class Car {
   
    // 汽车无法使用普通的CDPlay
    private CDPlayerCarAdapter cdPlayerCarAdapter;

    public Car(CDPlayerCarAdapter cdPlayerCarAdapter) {
   
        this.cdPlayerCarAdapter = cdPlayerCarAdapter;
    }

    public void playCD(){
   
        cdPlayerCarAdapter.play();
    }
}

/** * 适配器模式 * *@Author cly *@Date 2021/08/31 1:52 *@Version 1.0 */
public class Adapter {
   
    public static void main(String[] args) {
   
        CDPlayer cdPlayer = new CDPlayer();

        Car car = new Car(new CDPlayerCarAdapter(cdPlayer));
        car.playCD();
    }
}

3. 源码实现

3.1 java.util.Enumeration

java.util.Enumeration JDK 1.0 提供用于遍历容器类的接口,但是一个公认的设计失误,所以 JDK 1.2 对其进行了重构,新增 Iterator 接口去迭代容器类。

JDK 为了保证向后兼容,就在容器工具类 java.util.Collections 的 enumeration 方法中使用了适配器模式,用 Collection#iterator() 构造 Enumeration 对象,源码如下:

public class Collections {
   
    
    private Collections() {
   
    }    
	
    public static <T> Enumeration<T> enumeration(final Collection<T> c) {
   
        return new Enumeration<T>() {
   
            private final Iterator<T> i = c.iterator();

            public boolean hasMoreElements() {
   
                return i.hasNext();
            }

            public T nextElement() {
   
                return i.next();
            }
        };
    }
}

3.2 Spring AOP

Spring AOP的增强或通知(Advice)使用到了适配器模式,Spring MVC中也是用到了适配器模式适配Controller