策略模式
一、策略模式:
如果说简单工厂模式对对象分类,
那么策略模式就是对相似逻辑算法分类,
将算法的切换变成一个目标可变的行为,
由策略决定行为。
二、基本思路:
1.创建策略抽象类,定义所有支持的算法的公共接口;
2.继承抽象类,策略具体化;
3.定义Context类作为上下文承接的角色,是使用了某种策略的类,通过策略改变自身行为。
三、简单样例:
以简单收银软件为例,灵活解决原价、打折、返现、返积分等问题。
/** * 策略抽象类 * 定义收费抽象方法 */ abstract class CashSuper{ public abstract double acceptCash(double money); }
/** * 具体策略的实现 * 将收费方式具体化,例如按照原价,或者打折或者满价返现等等 */ //正常收费 class CashNormal extends CashSuper{ @Override public double acceptCash(double money) { return money; } } //打折收费 class CashRebate extends CashSuper{ private double cashRebate=1; CashRebate(double moneyRebate){//传入折扣率,之前初始化为1 this.cashRebate=moneyRebate; } @Override public double acceptCash(double money) { return money*cashRebate;//折扣后 } } //收费返利 class CashReturn extends CashSuper{ private double cashCondition=0; private double cashReturn=0; //满cashCondition,送cashReturn CashReturn(double cashCondition, double cashReturn){ this.cashCondition=cashCondition; this.cashReturn=cashReturn; } @Override public double acceptCash(double money) { double result=money; if (money>=cashCondition){ result=money-Math.floor(money/cashCondition)*cashReturn; } return result; } }
/** * 接收具体策略,并产生不同的行为 * 根据收费策略,决定费用计算方法 */ class Context{ private CashSuper cashSuper; //通过构造方法传入具体的收费策略 public Context(CashSuper cashSuper){ this.cashSuper=cashSuper; } public double getResult(double price){ //根据收费策略的不同,用不同的计算方法获得具体收费金额。 return cashSuper.acceptCash(price); } }
/** * 选择策略 * 客户端选择收费方法,即可得到响应的结果, * 具体算法已经跟客户程序隔离 */ class Main{ public static Context chooseStrategy(String type){ Context context=null; //根据收费类型不同,将相应的策略对象传入Context中, // 之后Context将产生对应行为,最终得出结果 switch (type) { case "正常收费": context = new Context(new CashNormal()); break; case "打8折": context = new Context(new CashRebate(0.8)); break; case "满300返100": context = new Context(new CashReturn(300, 100)); break; default: break; } return context; } public static void main(String[] args) { double single=12;//单价 double num=3;//数量 double totalPrice=0;//总价 Context context=null; String[] types={"正常收费","打8折","满300返100"}; context=chooseStrategy(types[1]); //进行计算 totalPrice=context.getResult(single*num); System.out.println("应收费:"+totalPrice); } }