设计模式 | 策略模式
程序员文章站
2023-02-20 23:19:23
参考:https://www.cnblogs.com/lewis0077/p/5133812.html(深入解析策略模式) 参考:https://www.cnblogs.com/lewis0077/p/5133812.html(深入解析策略模式) 定义: 策略模式定义了一系列的算法,并将每一个算法封 ......
参考:(深入解析策略模式)
定义:
策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
结构:(书中的图,侵删)
1.一个定义公共方法的接口
2.若干实现了接口的具体实现
3.上下文context,用于跟客户端和策略之间交互
例子:
经过我的思考,我感觉上一篇的简单工厂模式使用的计算器的例子,似乎用在这里更为恰当吧。
我们的目的是选择不同的算法,而不是创建不同的对象。
但其实两者的表现形式很像,只是用途不同。
所以,我这里继续用计算器的例子。(书中用的是商户采取不同的优惠策略的例子)
公共接口:
package designpattern.strategy; public interface calculate { public double calculate(double num1, double num2); }
具体实现(加减乘除方法):
package designpattern.strategy; public class plus implements calculate { @override public double calculate(double num1, double num2) { return num1 + num2; } }
package designpattern.strategy; public class minus implements calculate { @override public double calculate(double num1, double num2) { return num1 - num2; } }
package designpattern.strategy; public class multiply implements calculate { @override public double calculate(double num1, double num2) { return num1 * num2; } }
package designpattern.strategy; public class divide implements calculate { @override public double calculate(double num1, double num2) { return num1 / num2; } }
上下文:
package designpattern.strategy; public class calculatecontext { calculate calculate; public calculatecontext(calculate calculate) { super(); this.calculate = calculate; } public double calculate(double num1, double num2) { return calculate.calculate(num1, num2); } }
客户端:
package designpattern.strategy; import java.util.scanner; public class calculator { public static void main(string[] args) { scanner scanner = new scanner(system.in); system.out.println("请输入一个数字"); double num1 = scanner.nextdouble(); system.out.println("请输入一个运算符:+、-、*、/"); string operator = scanner.next();// 不能用nextline(),会把上一个回车给吸收 system.out.println("请输入一个数字"); double num2 = scanner.nextdouble(); switch (operator) { case "+": system.out.println(new calculatecontext(new plus()).calculate(num1, num2)); break; case "-": system.out.println(new calculatecontext(new minus()).calculate(num1, num2)); break; case "*": system.out.println(new calculatecontext(new multiply()).calculate(num1, num2)); break; case "/": system.out.println(new calculatecontext(new divide()).calculate(num1, num2)); break; default: break; } scanner.close(); } }
这样的写法,还是把判断的任务交给了客户端。
可以稍加改善,把判断交给上下文context。
上下文:
package designpattern.strategy; public class calculatecontext2 { calculate calculate; public calculatecontext2(string operate) { super(); switch (operate) { case "+": this.calculate = new plus(); break; case "-": this.calculate = new minus(); break; case "*": this.calculate = new multiply(); break; case "/": this.calculate = new divide(); break; } } public double calculate(double num1, double num2) { return calculate.calculate(num1, num2); } }
客户端:
package designpattern.strategy; import java.util.scanner; public class calculator2 { public static void main(string[] args) { scanner scanner = new scanner(system.in); system.out.println("请输入一个数字"); double num1 = scanner.nextdouble(); system.out.println("请输入一个运算符:+、-、*、/"); string operator = scanner.next();// 不能用nextline(),会把上一个回车给吸收 system.out.println("请输入一个数字"); double num2 = scanner.nextdouble(); system.out.println(new calculatecontext2(operator).calculate(num1, num2)); scanner.close(); } }
这里使用了简单工厂模式的思想,传入一个参数,不管具体细节,获得所期望的对象,所以算是简单工厂模式和策略模式的结合。
总结:
策略模式能将我们从if-else中解放出来,当我们需要不停的写if-else的时候,可以想起策略模式。让我们的代码可扩展且更易于维护。