作用:将一个类的接口转换成另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
你只能通过网线才能上网,但你的电脑只有USB接口,这时你需要用到扩展坞。这个拓展坞就是一个适配器,它两端连接了电脑和网线,使得你的电脑能够上网。
角色分析:
- 目标接口:客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口(USB)
- 需要适配的类:需要适配的类或适配者类 (网线)
- 适配器:通过包装一个需要适配的对象,把原接口转换成目标对象 (扩展坞)
类形:
- 类适配器:继承被适配者
- 对象适配器:组合的方式,以被适配者作为自己的属性
对象适配器优点:
4. 一个对象适配器可以将多个不同的适配者适配到同一个目标
5. 可以适配一个适配者的子类,由于适配器和适配者之间是关联关系,根据“里氏代换原则”。适配者的子类也可通过该适配器进行适配
类适配器的缺点:
6. 对于Java、C#等不支持多继承的语言,一次只能适配一个类
7. 在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定局限性
使用场景:
8. 系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统要求,甚至没有这些类的源代码
9. 想创建一个可以重复使用的类,用于一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作
实例:gui、SpringMVC、SpringBoot…
代码:
NetToUSB 连接上网接口
/**
* 接口转换器的抽象实现
* 作用:处理请求,网线=>USB
*/
public interface NetToUSB {
public void handleRRequest();
}
Adaptee.java 被适配的网线类
/**
* 要被适配的类: 网线
*/
public class Adaptee {
public void request(){
System.out.println("连线上网...");
}
}
Adapter.java 类适配器
/**
* 类适配器:连接USB、网线
*/
public class Adapter extends Adaptee implements NetToUSB {
@Override
public void handleRRequest() {
//可以上网了
super.request();
}
}
Adapter2.java 对象适配器
/**
* 对象适配器:连接USB、网线
*/
public class Adapter2 implements NetToUSB {
private Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void handleRRequest() {
//可以上网了
adaptee.request();
}
}
Computer.java 电脑
public class Computer {
//电脑连接上转接器才可以上网
public void net(NetToUSB adapter){
//上网的具体实现,找一个转接头
adapter.handleRRequest();
}
public static void main(String[] args) {
// 电脑
Computer computer = new Computer();
// 网线
Adaptee adaptee = new Adaptee();
// 适配器
Adapter2 adapter = new Adapter2(adaptee);
computer.net(adapter);
}
}