文章目录
适配器模式
定义:将一个接口转换成客户希望的另一个接口,适配器模式使得接口不兼容的一些类可以一起工作。主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
角色:
适配器模式具有如下角色:
- 目标抽象类:定义客户需要使用的特定领域的接口
- 适配器类:对目标抽象类和适配者类进行适配
- 适配者类:定义了已经存在的接口,包含了实际的业务逻辑方法。
- 客户类:针对目标抽象接口进行编程
说明:给定一个场景:现在Target目标类中定义方法名字为method1(),而且Client客户端已经针对该方法进行编程。现在需要用到B类的method2()方法来满足客户端的需求,也就是替换method1()方法,但是Client客户端要求的接口method1()和B类中的接口method2()不一样,这就需要用到适配器模式。
做法:编写一个适配器类,用作Client客户端和B类之间的桥梁。
分类:
- 类适配器:适配器和适配者存在继承、实现关系。此时Target为接口。
/**
* 适配器类
* 将输入的220V电压转化为手机可以用的5V
*/
public class Adapter220 extends Voltage_220 implements Target{
@Override
public void need5V() {
System.out.println("我是适配器,输入电压为:"+super.getV()+"V 输出电压为:"+super.getV()/44+"V");
}
}
对象适配器:适配器和适配者存在组合、聚合关系。此时Target为抽象类或接口。
/**
* 适配器类
* 将输入的220V电压转化为手机可以用的5V
*/
public class Adapter220 extends Target{
private Voltage_220 voltage_220=new Voltage_220();
@Override
public void need5V() {
System.out.println("我是适配器,输入电压为:"+voltage_220.getV()+"V 输出电压为:"+voltage_220.getV()/44+"V");
}
}
优点:
公共优点:
- 将目标类与适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有代码。
- 灵活、扩展性好,符合“开闭原则”。不同的逻辑业务,只需要编写一个新的适配器,更换即可,不需要修改原有代码。
- 透明性,复用性好。具体的实现封装在适配者类中,对客户端来说是透明的,适配器类提高了适配者类的复用。
类适配器模式单独优点:
适配器类是适配者类的子类,可以在适配器类中置换一些适配者类的方法,使得适配器灵活性好。
对象适配器模式单独优点:
可以将多个不同的适配者类适配到同一目标,同一个适配器可以把适配者类和它的子类都适配到目标接口。
缺点:
类适配器模式缺点:不支持多重继承,有一定的局限性,所以不能适配多个类在目标接口。
对象适配器模式单独缺点:对适配者类的方法置换实现起来极其复杂。
适用场景:
- 系统需要使用现有的类,但是这些类的接口不符合系统的需要。
- 想要提高这个类的复用性。
实例说明:
结构:使用对象适配器模式
场景:家庭用电都是220V,但是手机都是5V下进行充电,此时需要充电器从中进行适配。
Target
/**
* Target目标抽象接口
*
* 提供手机充电标准 5V电压下
*/
public class Target {
public void need5V(){};
}
Voltage_220
/**
* Voltage_220 适配者类
* 提供220V电压
*/
public class Voltage_220 {
private final int v=220;
public int getV() {
return v;
}
}
Adapter220
/**
* 适配器类
* 将输入的220V电压转化为手机可以用的5V
* 对象适配器
*/
public class Adapter220 extends Target{
private Voltage_220 voltage_220=new Voltage_220();
@Override
public void need5V() {
System.out.println("我是适配器,输入电压为:"+voltage_220.getV()+"V 输出电压为:"+voltage_220.getV()/44+"V");
}
}
/**
* Phone客户类
* 根据抽象类进行编程
* 只能在5V电压下进行充电
*/
public class Phone {
public static void main(String[] args) {
Target target=new Adapter220();
target.need5V();
/**结果如下:
我是适配器,输入电压为:220V 输出电压为:5V
*/
}
}
参考书籍:
设计模式.刘伟.胡志刚.郭克华.清华大学出版社