策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。
这个模式涉及到三个角色:
● 环境(Context)角色:持有一个Strategy的引用。
● 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
● 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
Context:
public class CashContext {
private Strategy cs;
public CashContext(Strategy cssuper){
this.cs = cssuper;
}
public double getResult(double money){
return cs.algorInterface(money);
}
}
Strategy:
public abstract class Strategy {
double money;
public Strategy(double m){
this.money = m;
}
public double getMoney(){
return this.money;
}
public void setMoney(double m){
this.money = m;
}
public abstract double algorInterface(double m);
}
ConcreteStrategy:
//正常收费
public class CashNormal extends Strategy {
public CashNormal(double m){
super(m);
}
public double algorInterface(double m){
return m;
}
}
//打折
public class CashRebate extends Strategy {
private double rebate = 0;
public CashRebate(double m,double r){
super(m);
rebate = r;
}
public double algorInterface(double m){
return m*rebate;
}
}
//满X返Y
public class CashReturn extends Strategy {
private double _return = 0; //满五百反一百, 100
private double _condition = 0; //500
public CashReturn(double m,double c,double r){
super(m);
_return = r;
_condition = c;
}
public double algorInterface(double m){
double result = m;
if(m > _condition){
result = m - ((int)(m / _condition))*_return;
}
return result;
}
}
客户端
import java.util.ArrayList;
import java.util.List;
public class CashClient {
public static void main(String[] args) {
List<String> str = new ArrayList<String>();
str.add("正常收费");
str.add("打8折");
str.add("满300减100");
CashContext cashContext = null;
for(String ss : str){
switch(ss){
case "正常收费" :
cashContext = new CashContext(new CashNormal(500));
break;
case "打8折" :
cashContext = new CashContext(new CashRebate(500, 0.8));
break;
case "满300减100" :
cashContext = new CashContext(new CashReturn(500, 300,100));
break;
default :
System.out.println("打烊了.");
}
double re = cashContext.getResult(500);
System.out.println(re);
}
}
}
结果:
500.0
400.0
400.0
总结:
策略模式主要体现为封装变化点,这种设计思想很重要,看到题目是超市收费,给出的几种收费方式的时候,要想到如何涵盖这些收费方式也就是算法,如何利于后续的扩展,同时如何降低模块之间的耦合度。
策略模式和简单工程模式比较:
简单工厂模式:客户端传一个条件进工厂类,工厂类根据条件创建相应的产品类对象,并return给客户端,供客户端使用。即客户端使用的是工厂类生产的产品对象。
策略模式:客户端创建一个Context类对象a(可以看作是工厂模式中工厂类),创建一个策略对象并传参给对象a,然后客户端使用a对象的某些方法来使用前面传参进来的策略,即客户端是通过a对象使用策略的。
简单的说,
1、工厂模式根据条件生产出产品给客户端用。而策略模式是客户端使用传参给Context的策略(你也可以理成产品),传入策略的不同,调用同样方法得到的结果也不同。
2、工厂模式:客户端是使用工厂类生产的对象进行操作,策略模式:客户端使用自己传给Context的策略的对象进行操作。
参考文章:
http://blog.youkuaiyun.com/zhangliangzi/article/details/52161211
https://www.cnblogs.com/langtianya/archive/2013/03/08/2950934.html