1.定义
定义一系列的算法,把他们封装起来,并且使他们可以相互替换,此模式使算法可以独立于使用它的客户而变化。
2.适用场景
1)需要使用一个算法的不同实现。
2)算法使用客户不应该知道的数据,可以通过策略模式避免暴露与算法相关的数据结构。
3.类图
1)DiscountStrategy:是策略接口,其中定义所支持算法的公共接口price()。
2)DefaultStrategy、PriceAStrategy、PriceBStrategy:是具体策略,分别实现某种不同的算法。
3)Context:上下文。维护一个DiscountStrategy的引用,提供setter方法,用于可以替换算法的实现,并提供一个方法getPrice()供客户端访问策略接口。
4)StrategyMain:客户端。
4.代码示例
public interface DiscountStrategy {
public void price();
}
public class DefaultStrategy implements DiscountStrategy {
@Override
public void price() {
System.out.println("没有任何折扣!");
}
}
public class PriceAStrategy implements DiscountStrategy {
public void price(){
System.out.println("我给你打8折!");
}
}
public class PriceBStrategy implements DiscountStrategy{
public void price(){
System.out.println("年底甩货,我打5折!");
}
}
public class Context {
DiscountStrategy strategy;
public Context(){
this.strategy = new DefaultStrategy();//提供了一个默认实现,这样客户端可以不传入具体策略。
}
public Context(DiscountStrategy strategy){
this.strategy = strategy;
}
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public void getPrice(){
strategy.price();
}
}
public class StrategyMain {
public static void main(String[] args) throws Exception{
DiscountStrategy strategy = new PriceAStrategy();
Context ctx = new Context();
// ctx.setStrategy(strategy);
ctx.getPrice();
}
}
输出结果:
没有任何折扣!
5.策略模式的一个小缺点
因为所有的具体实现都依赖同一个接口,假如示例中DefaultStrategy具体策略实现可以不依赖输入参数,而PriceAStrategy需要依赖输入参数,需要由Context为其提供信息,那么这样即使DefaultStrategy不需要任何信息,它的实现中仍然需要有入参,但是却用不到。