什么是策略模式?
策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法,并且由客户端决定调用那个算法。这种类型的设计模式属于行为型模式。
本质
- 分离算法,选择实现。
开发中常见的场景
- Javase的GUI编程中,布局管理。
- Spring框架中,Resource接口,资源访问策略。
- javax.servlet.http.HttpServlet#service()。
组成编辑
- 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用
场景
某个市场人员接单后的报价策略(CRM系统中常见问题)。报价策略很复杂,可以简单做如下分类:
- 普通客户小批量报价
- 普通客户大批量报价
- 老客户小批量报价
- 老客户大批量报价
具体选哪个报价策略,这需要根据实际情况来确定。这时候,我们采用策略模式即可。
类图
代码
抽象策略角色
package com.match.strategy;
/**
* 抽象策略角色
* @author Match
*
*/
public interface Strategy
{
public double getPrice(double standardPrice);
}
具体策略角色
package com.match.strategy;
/**
* 新顾客小批量
* @author Match
*
*/
public class NewCustomerFewStrategy implements Strategy
{
@Override
public double getPrice(double standardPrice)
{
System.out.println("不打折,原价");
return standardPrice;
}
}
package com.match.strategy;
/**
* 新顾客大批量
* @author Match
*
*/
public class NewCustomerManyStrategy implements Strategy
{
@Override
public double getPrice(double standardPrice)
{
System.out.println("打九折");
return standardPrice*0.9;
}
}
package com.match.strategy;
/**
* 老顾客小批量
* @author Match
*
*/
public class OldCustomerFewStrategy implements Strategy
{
@Override
public double getPrice(double standardPrice)
{
System.out.println("打八五折");
return standardPrice*0.85;
}
}
package com.match.strategy;
/**
* 老顾客大批量
* @author Match
*
*/
public class OldCustomerManyStrategy implements Strategy
{
@Override
public double getPrice(double standardPrice)
{
System.out.println("打八折");
return standardPrice*0.8;
}
}
环境角色
package com.match.strategy;
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
* 如果使用spring的依赖注入功能,还可以通过配置文件,动态的注入不同策略对象,动态的切换不同的算法。
* @author Match
*
*/
public class Context
{
private Strategy strategy;//当前采用的算法对象
/**
* 可以通过构造器来注入
* @param strategy
*/
public Context(Strategy strategy)
{
super();
this.strategy = strategy;
}
/**
* 可以通过set方法来注入
* @param strategy
*/
public void setStrategy(Strategy strategy)
{
this.strategy = strategy;
}
public void printPrice(double s)
{
System.out.println("您该报价:"+strategy.getPrice(s));
}
}
客户端
package com.match.strategy;
public class Client
{
public static void main(String[] args)
{
Context ctx = new Context(new OldCustomerManyStrategy());
ctx.printPrice(1000);
}
}
测试输出
打八折
您该报价:800.0