策略模式(Strategy Pattern)
什么是策略?策略就是"可以实现目标方案的集合"。策略模式中,一个类的行为或动作可以在运行时候改变,比如,用户在操作计算器的时候,输入加法和数字的时候,得到的是和;输入减法和数字的时候,得到的是差,这就是运行时候改变动作。
在设计面向对象程序的时候,需要注意的是:
1. 分出程序中易发生变化的部分,并加以抽象。
2. 针对接口编程,而不是针对实现编程。
3. 多用组合,少用继承@1
举一个例子先:
使用Java实现一个简单计算器,需要为用户实现加,减,乘,除四种运算服务。
实现这个需求的方法有多种,可以写一个switch case语句进行遍历比较,也可以使用if else进行选择。
我们这里尝试使用策略模式解决问题。
1. 将所有的操作提炼出来 生成一个操作类 Operation
操作类Operation
package xxxx
abstract class Operation{
public abstract void Caclulate(double i, double j);
}
2. 提供加法(Add),减法(Sub),乘法(Mul)和除法(Div)这四种服务。
/* 加 */
public class Add implement Operation {
public void Calculate(double i, double j) {
System.out.println(i+j);
}
}
/* 减 */
public class Sub implement Operation {
public void Calculate(double i, double j) {
System.out.println(i-j);
}
}
/* 乘 */
public class Mul implement Operation {
public void Calculate(double i, double j) {
System.out.println(i*j);
}
}
/* 除 */
public class Div implement Operation {
public void Calculate(double i, double j) {
System.out.println(i/j);
}
}
3. 将这些操作类作为一个计算器的(Calculator)属性。
class Calculator {
Operation Opt;
Calculator(Operation operation) { //参数operation 是传入的操作(加减乘除)
this.Opt = operation;
}
public void Calculate(double i, double j) //计算机提供计算方法
{
Opt.calculate(i, j);
}
}
4. 用户测试:计算器已经准备好,用户开始使用:
生成计算器实体类,输入数字和操作,并拿到结果。
public class UserTest {
public static void main(String[] args) {
Calculator calculator;
/* 加法操作 */
calculator = new Calculator(new Add());
calculator.Calculate(3,2);
/* 减法操作 */
calculator = new Calculator(new Sub());
calculator.Calculate(3,2);
/* 乘法操作 */
calculator = new Calculator(new Mul());
calculator.Calculate(3,2);
/* 除法操作 */
calculator = new Calculator(new Div());
calculator.Calculate(3,2);
}
}
好处:
松耦合,符合上述五大原则中的单一职责,开放封闭的原则。
用户直接调用固定的接口,放入不同的操作即可完成所有的工作。
易扩展:
即使后期有其他运算要加入进来,不需要修改原有的代码,只需要添加相应的类,继承接口,即可完成扩展。(对扩展开放,对修改封闭)
易维护:
修改一种运算(策略)不会影响到其他运算(策略)的正常使用。
问题:
@1:既然多用组合少用继承,那么代码复用性如何得以保证? 什么时候该使用继承,什么时候必须使用继承呢?
参考:
https://blog.youkuaiyun.com/m15712884682/article/details/52993085#t0
https://blog.youkuaiyun.com/dingsai88/article/details/51706268