说明:本文是《大话设计模式》一书的学习文摘和网上相关信息文摘,原书代码例子用C#写,下面用Java改写。
1、策略模式:定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
2、策略模式由三种角色组成:
(1)抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
(2)具体策略角色:包装了相关的算法和行为。
(3)环境角色:持有一个策略类的引用,最终给客户端调用。
3、策略模式的UML类图
4、算法实现
package demo3;
/**
* 抽象算法的策略类,定义所有支持的算法的公共接口
*
*/
abstract class Strategy {
//算法方法
public abstract void AlgorithmInterface();
}
package demo3;
/**
* 具体算法A
*
*/
public class ConcreteStrategyA extends Strategy {
//算法A实现方法
@Override
public void AlgorithmInterface() {
System.out.println("算法A的实现");
}
}
package demo3;
/**
* 具体算法B
*
*/
public class ConcreteStrategyB extends Strategy {
///算法B实现方法
@Override
public void AlgorithmInterface() {
System.out.println("算法B的实现");
}
}
package demo3;
/**
* 具体算法C
*
*/
public class ConcreteStrategyC extends Strategy {
@Override
public void AlgorithmInterface() {
System.out.println("算法C的实现");
}
}
package demo3;
/**
* 上下文,维护一个对策略类对象的引用
*
*/
public class Context {
Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void contextInterface(){
strategy.AlgorithmInterface();
}
}
package demo3;
/**
* 客户端代码:实现不同的策略
*
*/
public class Demo3 {
public static void main(String[] args) {
Context context;
context = new Context(new ConcreteStrategyA());
context.contextInterface();
context = new Context(new ConcreteStrategyB());
context.contextInterface();
context = new Context(new ConcreteStrategyC());
context.contextInterface();
}
}
5、一个例子:商场收银软件,根据商场活动可以打折、满多少减多少等,用策略结合简单工厂实现。
package demo2;
/**
* 现金收费抽象类
*/
public abstract class CashSuper {
//参数为原价,返回为当前价
public abstract double accptCash(double money);
}
package demo2;
/**
* 正常收费子类
*/
public class CashNormal extends CashSuper {
@Override
public double accptCash(double money) {
return money;
}
}
package demo2;
/**
* 打折收费子类
*/
public class CashRebate extends CashSuper {
private double moneyRebate = 1d;
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double accptCash(double money) {
return money * moneyRebate;
}
}
package demo2;
/**
* 返利收费子类
*/
public class CashReturn extends CashSuper {
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(double moneyCondition, double moenyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moenyReturn;
}
@Override
public double accptCash(double money) {
double result = money;
if(money >= moneyCondition)
result = money - Math.floor(money / moneyCondition) * moneyReturn;
return result;
}
}
package demo2;
/**
* 策略与简单工厂结合:将实例化具体策略的过程由客户端转移到这里Context类
*/
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 getReslt(double money){
return cs.accptCash(money);
}
}
package demo2;
/**
* 客户端使用
*/
public class Demo2 {
public static void main(String[] args) {
//正常收费
CashContext cc = new CashContext("正常收费");
double totalPrices = cc.getReslt(500);//原价
System.out.println(totalPrices);
//满300返100
cc = new CashContext("满300返100");
totalPrices = cc.getReslt(500);//原价
System.out.println(totalPrices);
}
}