设计模式之适配器模式
适配器模式介绍:
1、适配器模式是将某个类的接口转化成客户端期望的另一个接口表示,主要目的是为了兼容性,让原本因接口原因不匹配不能一起工作的两个类可以协同工作。也叫包装器。
2、适配器模式属于结构性模式。
3、主要分类:类适配器模式,对象适配器模式,接口适配器模式。
适配器模式最大的作用就是将原本不兼容的接口融合在一起工作。
适配器模式工作原理:
1、将一个类的接口转化成另一种接口,让原本接口不兼容的类可以兼容。
2、从用户的角度看不到被适配者,是解耦的。
3、用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。
4、用户接收到反馈结果,感觉只是和目标接口交互。
类适配器:
例子:现在的电源是220V的交流电,但是手机使用的是5V的直流电,所以需要,特别转化下,这边的充电器就是相当于适配器。
类的关系图如下:
Voltage220V.java
public class Voltage220V { public int output220v() { int src = 220; System.out.println("电压为:" + src + "V"); return src; } }
IVoltage5V.java
public interface IVoltage5V { int output5V(); }
VoltageAdapter.java
public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output5V() { int src = output220v(); int dstV = src /44; return dstV; } }
Phone.java
public class Phone { public void charging(IVoltage5V iVoltage5V){ if(iVoltage5V.output5V() == 5){ System.out.println("电压为5V,可以开始充电"); } else if(iVoltage5V.output5V() != 5){ System.out.println("电压不为5V, 无法充电"); } } }
Client.java
public class Client { public static void main(String[] args) { System.out.println("类适配器模式"); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }
类适配器的分析:
1、java是单继承方式,所以类适配器继承src类后,造成的问题是,要求dst必须是接口,有一定的局限性。
2、src类的方法在Adapter中都会暴露出来,也增加了使用的成本。
3、由于适配器类继承了src类,所以可以根据需求重写src类的方法,使得Adapter的灵活性增强了。
对象适配器:
还是上面电压的问题
基本思路和类适配器模式相同,只是修改Adapter类,不是继承src类,二是持有src类的实例,来解决兼容性的问题。即持有src类的对象,实现dst类接口,完成src-dst的适配。
类的关系图:
改写为VoltageAdapter2
//对象适配器 public class VoltageAdapter2 implements IVoltage5V{ private Voltage220V voltage220V; public VoltageAdapter2(Voltage220V voltage220V) { this.voltage220V = voltage220V; } @Override public int output5V() { int src = voltage220V.output220v(); int dstV = src /44; return dstV; } }
Client.java
public class Client { public static void main(String[] args) { System.out.println("对象配器模式"); Phone phone = new Phone(); phone.charging(new VoltageAdapter2(new Voltage220V())); } }
这个时候适配器和src是聚合的关系,所以不需要要求dst类必须是接口。也可以是抽象类。
接口适配器:
当不需要全部实现接口提供的方法时,可以先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认的实现(空方法),那么该抽象类的子类可以有选择的覆盖父类的某些方法来实现需求。可以通过匿名内部类实现。
其中可以建一个AbsA的匿名方法。重写需要的方法即可。
代码实现如下:
Interface4.java
public interface Interface4 { public void m1(); public void m2(); public void m3(); public void m4(); }
AbsAdapter.java中只是空实现。
public abstract class AbsAdapter implements Interface4 { @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } }
客户端:
public class InterfaceAdapterClient { public static void main(String[] args) { AbsAdapter absAdapter = new AbsAdapter() { @Override public void m1() { System.out.println("使用了m1的方法"); } }; absAdapter.m1(); } }