Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说GoF之适配器模式、策略模式详解,希望能够帮助你!!!。
适配器模式(Adapter Pattern)
将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
优点
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性和扩展性都非常好,符合“开闭原则”。
缺点:
1、过多地使用适配器,会让系统变复杂。比如,明明看到调用的是A 接口,其实内部被适配成了 B 接口的实现。如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
类适配器模式(adapter pattern)
具体实现:通过电源适配器,将电源输入220V(适配者)转换为5V输出(目标)。
//目标角色 public interface PowerTarget{ public int output5V(); } //适配者角色 public class PowerAdaptee{ private int output = 220; public int output220V() { System.out.println("电源输出电压:" + output); return output; } } //适配器角色 public class PowerAdapterextends PowerAdapteeimplements PowerTarget{ @Override public int output5V() { int output =output220V(); System.out.println("电源适配器开始工作,此时输出电压是:" + output); output = 5; System.out.println("电源适配器工作完成,此时输出电压是:" + output); return output; } } 电源适配器类实现了电源目标,继承了适配者。 //类适配器模式测试 public class ClassAdapterPatternTest{ public static void main(String[] args) { PowerTargettarget = new PowerAdapter(); target.output5V(); } }
对象适配器模式(object adapter pattern)
对象适配器模式在运行时实现target(目标)接口。在这种适配器模式中,适配器包装了一个类实例。适配器通过调用包装对象实例的方法实现适配。
代码示例和类适配器模式只有Adapter类有不同,其他都一样,只贴上Adapter类。
//适配器角色 public class PowerAdapterimplements PowerTarget{ private PowerAdaptee powerAdaptee; public PowerAdapter(PowerAdapteepowerAdaptee) { super(); this.powerAdaptee = powerAdaptee; } @Override public int output5V() { int output = powerAdaptee.output220V(); System.out.println("电源适配器开始工作,此时输出电压是:" + output); output = 5; System.out.println("电源适配器工作完成,此时输出电压是:" + output); return output; } }
实现了PowerTarget(目标角色),在创建对象时引入PowerAdaptee(适配者角色)。
缺省适配器模式(defaultadapter pattern)(客户端,继承b,调用b中的方法,不必直接实现a(直接实现a需要实现a中的所有的方法))
当不需要全部实现接口提供的方法时,可以设计一个适配器抽象类实现接口,并为接口中的每个方法提供默认方法,抽象类的子类就可以有选择的覆盖父类的某些方法实现需求,它适用于一个接口不想使用所有的方法的情况。
在java8后,接口中可以有default方法,就不需要这种缺省适配器模式了。接口中方法都设置为default,实现为空,这样同样同样可以达到缺省适配器模式同样的效果。
策略模式(Strategy Pattern)也叫 政策模式(Policy Pattern)。
指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。
优点:
1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。
缺点:
1、策略类会增多。
2、所有策略类都需要对外暴露。
具体实现:建立加减乘算法族,解决在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
//创建一个接口,定策略或算法的行为。 public interface Strategy{ public int doOperation(int num1, int num2); } //创建实现接口的实体类,里面包含具体的策略或算法实现。利用多态,使行为在不同场景下产生不同结果。 public class OperationAddimplements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } } public class OperationSubstractimplements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } } public class OperationMultiplyimplements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 * num2; } } //创建Context类,用来操作策略的上下文环境,屏蔽高层模块(客户端)对策略,算法的直接访问,封装可能存在的变化; public class Context { private Strategy strategy; public Context(){ } public SetStrategy(Strategy strategy){ this.strategy = strategy; } public int executeStrategy(int num1, int num2){ return strategy.doOperation(num1, num2); } } //使用 Context 来查看当它改变策略 Strategy 时的行为变化。 public class StrategyPatternClient{ public static void main(String[] args) { Contextcontext = new Context(); context.SetStrategy(new OperationAdd()); System.out.println("10 + 5 =" + context.executeStrategy(10, 5)); context.SetStrategy(new OperationSubstract()); System.out.println("10 - 5 =" + context.executeStrategy(10, 5)); context.SetStrategy(new OperationMultiply()); System.out.println("10 * 5 =" + context.executeStrategy(10, 5)); } }
输出结果:
10 + 5 = 15
10 - 5 = 5
10 * 5 =50
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
原文:https://mp.weixin.qq.com/s/g20WQyzJNmvkH-kLPZRYBA
作者:专注一行代码
来源:微信公众号
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。