1. 现实场景
在销售产品时,为了促销,经常会进行打折。针对不同的时间、不同的消费群体,采用的打折策略也会不同。比如有的打八折,有的买一送一。这种动态的调整销售策略的行为,就是策略模式在现实生活中的应用。
2. 需求场景
一个大公司有两个子公司,吉林子公司和河北子公司,每个子公司都要计算薪资。薪资的计算包括基本工资、社会保险和个人所得税。
一般思路,使用模板方法模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public abstract class SalaryTemplate { public void Compute() { computeSalary(); computeInsurance(); computeTax(); }
public abstract void computeSalary();
public abstract void computeInsurance();
public abstract void computeTax(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class JiLinSalary extends SalaryTemplate { public void computeSalary() { System.out.println("采用吉林算法计算基本工资"); }
public void computeInsurance() { System.out.println("采用吉林算法计算保险"); }
public void computeTax() { System.out.println("采用吉林算法计算所得税"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class HeBeiSalary extends SalaryTemplate { public void computeSalary() { System.out.println("采用河北算法计算基本工资"); }
public void computeInsurance() { System.out.println("采用河北算法计算保险"); }
public void computeTax() { System.out.println("采用河北算法计算所得税"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Client { public static void main(String[] args) { SalaryTemplate jilin = new JiLinSalary() SalaryTemplate hebei = new HeBeiSalary() jilin.computeSalary() jilin.computeInsurance() jilin.computeTax() hebei.computeSalary() hebei.computeInsurance() hebei.computeTax() } }
|
3. 解决办法
但是,如果实现到这里,还是有问题的,那就是类的职责不清。这个模板类,既要计算基本工资,又要计算社会保险,还要计算个人所得税。违反了单一职责原则。那该如何设计呢?很明显,需要把计算基本工资、社会保险、个人所得税的功能进行拆分。
4. 总结
策略模式就是定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户端而独立变化。
策略模式主要由3部分组成:抽象策略类、具体策略类、上下文场景类。
优点:使用策略模式,可以替换继承关系的办法,也可以避免使用多重条件转移语句。
缺点:使用策略模式时客户端必须知道所有的策略类,并自行决定使用哪一个策略类,如果算法比较多,则会造成很多的策略类。
5. 源码分享
https://github.com/voidking/design-pattern-behavior.git
6. 参考文献
《易学设计模式》
《大话设计模式》
接口设计六大原则
软件设计六大设计原则讲解