总体来说设计模式分为三大类:
-
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
-
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
-
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
而今天主要讲的就是适配器模式。
适配器模式(Adapter Pattern)是一种结构型设计模式,它用于将一个类的接口转换成客户端所期望的另一个接口。适配器模式让原本不兼容的类能够一起工作,通过适配器提供的中间层来进行交互。主要目的是兼容性,让原本因接口不匹配不能工作的两个类可以协同工作。适配器模式(Adapter Pattern)又叫做变压器模式,它的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作,属于结构计模式。
适配器模式通常涉及以下几个角色:
- 目标接口(Target Interface):客户端所期望的接口,定义了客户端可以使用的方法。
- 适配器(Adapter):将被适配者的接口转换为目标接口,它是适配器模式的核心。适配器实现了目标接口,并包含一个对被适配者的引用,在目标接口方法中调用被适配者的方法来完成适配。
- 被适配者(Adaptee):需要被适配的旧接口或旧类。
适配器模式适用场景:
- 当现有的类或接口的接口与你的需求不兼容时,可以使用适配器模式来进行接口转换。
- 当你想要复用一个已经存在的类,但它的接口与其他类不匹配时,可以使用适配器模式来进行适应性改变。
适配器模式本质上是将现有的不兼容的接口转换为需要的接口,不需要改变原来的代码结构即可实现新的功能通常实现方式上有:
-
对象适配器:通过对象的组合来达到适配目的;
-
类适配器:通过类的继承或者接口的实现来达到适配目的;
-
接口适配器:通过实现接口的方式转换来达到适配的目的;
类适配器
类适配器的原理就是通过继承来实现适配器功能。具体做法:让 Adapter
实现 Target
接口,并且 继承 Adaptee
,这样 Adapter
就具备Target
和 Adaptee
可以将两者进行转化。
具体代码如下:
public class Adaptee {
public void specialRequest(){
System.out.println("处理特殊请求");
}
}
public interface Target {
void request();
}
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
System.out.println("处理普通请求");
super.specialRequest();
}
}public class Client {
public static void main(String[] args) {
Target target = new Adapter();
target.request();
}
}
结果:
对象适配器
对象适配器的原理就是通过组合来实现适配器功能。具体做法:让Adapter
实现 Target
接口,然 后内部持有 Adaptee
实例,然后再 Target
接口规定的方法内转换 Adaptee
。
具体代码实现很简单就是将Adapter
代码修改一下,原来是继承 Adaptee
,现在是持有 Adaptee
类图:
代码:
/**
* 适配器 对象适配器
*
* @author :liang_zh
* @date :2023-01-13 11:01:12
*/
public class Adapter2 implements Target {
private Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
System.out.println("处理普通请求");
adaptee.specialRequest();
}
}
//client:(客户端)
/**
* 对象适配器
*
* @param args arg游戏
*/
public static void main2(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter2(adaptee);
target.request();
}
接口适配器
接口适配器的关注点与类适配器和对象适配器的关注点不太一样,类适配器和对象适配器着重于将系统存在的一个角色(Adaptee)转化成目标接口(Target)所需内容,而接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多出许多空实现的方法,类显得很臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰。其实接口适配器和对象适配器就很像了无非是对象适配器关注点是一个对象的转换,接口可能是多个他的关注点不再是对象转换而是接口转换这些接口可能需要用到很多个源对象,也就是说这样设计之后转换器中持有的对象就可能是多个了。
类图:
优点:
-
能提高类的透明性和复用,现有的类复用但不需要改变。
-
目标类和适配器类解耦,提高程序的扩展性。
-
在很多业务场景中符合开闭原则。
缺点:
-
适配器编写过程需要全面考虑,可能会增加系统的复杂性。
-
增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
适配器模式是在现有的类和系统都不易修改的情况下使用,在系统设计之初慎用适配器模式,这样会导致代码可读性变差,不易维护。