策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
右边是策略接口以及它的实现类,左边是一个上下文,这个上下文会拥有一个策略,策略可以随意替换。这个上下文还含有个方法调用策略接口的方法。
商店的收费系统,有不同的收费模式。正常收费,打8折,满300减100。这3种收费模式,就是对应的具体策略,就是类图上面的StrategyA,StrategyB,StrategyC。这三种收费模式共同点都是收费,所以能够抽取一个共同的接口,3种收费模式分别实现该接口。至于上下文,主要管理策略模式,并提供方法给客户端调用。
定义收费的接口类:
package com.hjw.strategy; public interface CashSuper { public double acceptCash(double money); }正常收费的实现类:
package com.hjw.strategy; public class CashNormal implements CashSuper { @Override public double acceptCash(double money) { return money; } }打8折的实现类:
package com.hjw.strategy; public class CashRebate implements CashSuper { private double moneyRebate = 1; public CashRebate(String moneyRebate) { this.moneyRebate = Double.parseDouble(moneyRebate); } @Override public double acceptCash(double money) { return money * moneyRebate; } }满300减100的实现类:
package com.hjw.strategy; public class CashReturn implements CashSuper { private double moneyCondition = 0; private double moneyReturn = 0; 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.hjw.strategy; public class CashContext { private CashSuper cs; 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); } }客户端(使用策略模式):
package com.hjw.strategy; public class Test { public static void main(String[] args) { CashContext csuper = new CashContext("正常收费"); System.out.println(csuper.getResult(100)); csuper = new CashContext("满300减100"); System.out.println(csuper.getResult(100)); csuper = new CashContext("打8折"); System.out.println(csuper.getResult(100)); } }