在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。(我们封装的是其中变化的部分,如下面讲到的超市收银系统,由于存在返利和打折的行为,所以结账是不一样的策略,这里就需要考虑结账的变化)
介绍
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
任务:商业收银系统,营业员根据数量和单价向用户收费,在某些节日,商场会进行打折和返利活动,请根据需求编写系统
收费抽象类
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date: 2019-7-7 20:08
* */
abstract class CashSuper {
/*
* 由于设计的超市收银系统,在某些时候打折或者返利导致收钱的动作是一个变化
* ,所以这里可以把变化给封装起来
* */
public abstract double acceptCash(double money);
}
返利收费子类
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date: 2019-7-7 20:08
* */
public class CashReturn extends CashSuper{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(String moneyCondition,String moneyReturn){
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
double result = money;
if(money >= moneyCondition) {
result = money - Math.floor(money / moneyCondition) * moneyReturn;
}
return result;
}
}
打折收费子类
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date: 2019-7-7 20:08
* */
public class CashRebate extends CashSuper{
private double moneyRedate = 1d;
public CashRebate(String moneyRedate){
this.moneyRedate = Double.parseDouble(moneyRedate);
}
@Override
public double acceptCash(double money) {
return money*moneyRedate;
}
}
正常收费子类
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date: 2019-7-7 20:08
* */
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double money) {
return money;
}
}
收费工厂类(防止直接调用实现类,转为间接调用,可根据需求创建所需实例)
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date: 2019-7-7 20:08
* */
public class CashFactory {
public static CashSuper createCashAccpet(String type){
CashSuper cs = null;
switch(type){
case "正常收费":
cs = new CashNormal();
break;
case "满300返100":
cs = new CashReturn("300","100");
break;
case "打8折":
cs = new CashRebate("0.8");
break;
}
return cs;
}
}
客户端代码省略。。。
以上其实和就是上次所讲的简单工厂模式
策略模式下代码结构(其实我本人觉得和简单工厂模式和相似)
package com.liqiang.demo4;
/*
* @Author: liqiang
* @Date; 2019-7-7 21:00
* */
public class CashContext {
private CashSuper cs = null;
public CashContext(String type){
switch(type){
case "正常收费":
cs = new CashNormal();
break;
case "满300返100":
cs = new CashReturn("300","100");
break;
case "打8折":
cs = new CashRebate("0.8");
break;
}
}
public double getResult(double money){
return cs.acceptCash(money);
}
}