Java23种设计模式(四)适配器模式

tech2023-07-24  108

这是本人学习Java23种设计模式期间总结和记录,主要听的课程是尚硅谷——韩顺平老师的课程,这个课程可谓是非常详细了,推荐学习。

适配器模式在我学习完以后,个人感觉比较好理解,而且实际代码中也应该经常用得上,话不多说,大致理解如下:

目录

1、类适配器模式

2、对象适配器

3、接口适配器


大家都知道,不同国家不同地区的充电插头是不同的,如果你要出国旅游,必须要相对应的插座转换接口才行,而适配器模式就是类似于此,首先,被适配的东西就是外国的插座,因为那东西和你的不通用,所以必须被适配器适配;然后就是插座转换器,这个就是适配器本器了,是通过这个来适配不同的插孔,然后就是我们自己带的充电器,这个就是目标,一般你的手机需要的电压和插孔,就是你需要转换的目标,如下图所示:

适配器模式分为以下几种,都是随着需求慢慢演化而来:

1、类适配器模式

以生活中充电器的例子来讲解适配器,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们的目 dst(即 目标)是 5V 直流电

上代码:

//适配接口 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大原则里面,有个“合成复用原则”,根据此原则,在系统中尽量试用关联关系(聚合)来代替继承关系,于是有了下面的对象适配器:

2、对象适配器

基本思路和类的适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类,而是持有 src 类的实例,以解决兼容性的问题。 即:持有 src 类,实现 dst  类接口,完成 src->dst 的适配根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系对象适配器模式是适配器模式常用的一种

上代码:

//适配接口 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必须是接口。使用成本更低,更灵活。

但是在我们出门旅游的时候,难道要带上每个国家不同的转换接口吗,这样未免也太麻烦,于是有了下面的接口适配器

3、接口适配器

我们可以用接口里面写上每个国家插座的转换方法,然后用抽象类具体实现,在最后一层调用的时候就可以创建抽象类的实例,然后通过内部类重写抽象类中需要用到的个别方法就行了,代码思想如下:

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(); } }

这样就可以通过抽象方法,在需要的时候,通过内部类来确定具体需要的方法

最新回复(0)