这是本人学习Java23种设计模式期间总结和记录,主要听的课程是尚硅谷——韩顺平老师的课程,这个课程可谓是非常详细了,推荐学习。
适配器模式在我学习完以后,个人感觉比较好理解,而且实际代码中也应该经常用得上,话不多说,大致理解如下:
目录
1、类适配器模式
2、对象适配器
3、接口适配器
大家都知道,不同国家不同地区的充电插头是不同的,如果你要出国旅游,必须要相对应的插座转换接口才行,而适配器模式就是类似于此,首先,被适配的东西就是外国的插座,因为那东西和你的不通用,所以必须被适配器适配;然后就是插座转换器,这个就是适配器本器了,是通过这个来适配不同的插孔,然后就是我们自己带的充电器,这个就是目标,一般你的手机需要的电压和插孔,就是你需要转换的目标,如下图所示:
适配器模式分为以下几种,都是随着需求慢慢演化而来:
上代码:
//适配接口 public interface IVoltage5V { public int output5V(); } //被适配的类 public class Voltage220V {//输出 220V 的电压 public int output220V() { int src = 220; System.out.println("电压=" + src + "伏"); return src; } } public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output5V() { //获取到 220V 电压 int srcV = output220V(); int dstV = srcV / 44 ; //转成 5v return dstV; } } 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, 不能充电~~"); } } } public class Client { public static void main(String[] args) { System.out.println(" === 类适配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }这个就是将220V的电压转换成手机充电适用的5V电压,220V不能直接用,通过适配器转换成5V的电压充电刚刚好。
类适配器的注意事项和细节:
Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性;src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。但是这个方法有一个缺点,就是直接继承父类的问题,在我写的设计模式7大原则里面,有个“合成复用原则”,根据此原则,在系统中尽量试用关联关系(聚合)来代替继承关系,于是有了下面的对象适配器:
上代码:
//适配接口 public interface IVoltage5V { public int output5V(); } 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, 不能充电~~"); } } } //被适配的类 public class Voltage220V { //输出 220V 的电压,不变 public int output220V() { int src = 220; System.out.println("电压=" + src + "伏"); return src; } } public class VoltageAdapter implements IVoltage5V { private Voltage220V voltage220V; // 关联关系-聚合 //通过构造器,传入一个 Voltage220V 实例 public VoltageAdapter(Voltage220V voltage220v) { this.voltage220V = voltage220v; } @Override public int output5V() { int dst = 0; if(null != voltage220V) { int src = voltage220V.output220V();//获取 220V 电压 System.out.println("使用对象适配器,进行适配~~"); dst = src / 44; System.out.println("适配完成,输出的电压为=" + dst); } return dst; } } public class Client { public static void main(String[] args) { System.out.println(" === 对象适配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); } }对象适配器注意的事项和细节:
对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst必须是接口。使用成本更低,更灵活。但是在我们出门旅游的时候,难道要带上每个国家不同的转换接口吗,这样未免也太麻烦,于是有了下面的接口适配器
我们可以用接口里面写上每个国家插座的转换方法,然后用抽象类具体实现,在最后一层调用的时候就可以创建抽象类的实例,然后通过内部类重写抽象类中需要用到的个别方法就行了,代码思想如下:
public interface Interface4 { public void m1(); public void m2(); public void m3(); public void m4(); } //在 AbsAdapter 我们将 Interface4 的方法进行默认实现 public abstract class AbsAdapter implements Interface4 { //默认实现 public void m1() { } public void m2() { } public void m3() { } public void m4() { } } public class Client { public static void main(String[] args) { AbsAdapter absAdapter = new AbsAdapter() { //只需要去覆盖我们 需要使用 接口方法 @Override public void m1() { System.out.println("使用了 m1 的方法"); } }; absAdapter.m1(); } }这样就可以通过抽象方法,在需要的时候,通过内部类来确定具体需要的方法