策略模式

  顾名思义,我们来想象这样一个场景。商场有很多种打折方式,比如最近京东的满300送100,全场五折等等,商家销售的方式多种多样,如果我们用这样的场景来建模,你会怎么做呢?我们已经了解过了简单工厂模式,或许我们可以用简单工厂模式,抽象出一个用于计算最终消费者需要花多少钱的方法,然后对各种打折方式进行实现,增加一个工厂,根据客户端传递过来的标志量对打折方式的实例进行生产。这样做固然可以,但是我们可以想到,商家的打折方式是不确定的,可能今天采用这种打折方式,明天又会换一种打折方式,那么我们是不是得频繁修改这个工厂类呢?

  oh,no。这样做显然是糟糕的,虽然可以实现,但是它应该不是好的实现方式,那么应该怎么实现呢?这时候我们就要用到策略模式了。

  策略模式,它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。

  

我们来看抽象的策略类:

1 package strategy;
2 
3 //基本策略类,其他的算法类都会继承它
4 public abstract class BaseStrategy {
5     public abstract void doSomething();
6 }

然后是各种算法的实现类:

 1 public class StrategyA extends BaseStrategy{
 2     @Override
 3     public void doSomething() {
 4         System.out.println("strategyA:do something");
 5     }
 6 }
 7 
 8 public class StrategyB extends BaseStrategy{
 9     @Override
10     public void doSomething() {
11         System.out.println("strategyB:do something");
12     }
13 }

Context类:

 1 public class Context {
 2     private BaseStrategy strategy;
 3     
 4     public Context(BaseStrategy strategy) {
 5         this.strategy = strategy;
 6     }
 7     
 8     public void doSomeThing(){
 9         strategy.doSomething();
10     }
11     
12 }

客户端调用:

1 public class MainClass {
2     public static void main(String[] args) {
3         Context context = new Context(new StrategyA());
4         context.doSomeThing();
5         
6         context = new Context(new StrategyB());
7         context.doSomeThing();
8     }
9 }

  我们对比策略模式和简单工厂模式的最大不同就在于工厂的规模上,简单工厂需要维护一个大的工厂类,然后客户端可以根据标志量进行生产,但是当工厂需要频繁的更改时,就需要用到策略模式了,它最大好处在于不需要维护一个工厂,各种实现相分离,改变策略了,只需客户端在调用时作出变化,而这种变化对其他策略来说是不可见的,最大限度的降低了耦合度。

  所以说,策略模式是一种定义一系列算法的方法,从概念上看,这些算法都完成相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各类算法和调用算法类之间的耦合。

  context定义了可重用的方法,继承有助于析取这些算法中的公共功能。

  而且策略模式简化了测试,可以单独对每个算法进行测试。

  策略模式是用来封装算法的,在基本的策略模式中,选择所用具体实现的职责由客户端承担,而传递给Context。

posted @ 2012-10-23 12:17  寒剑飘香  阅读(170)  评论(0编辑  收藏  举报