策略模式(Strategy Method)

  策略模式可以看做“可插入式算法(Pluggable)”,将子类各自的行为和公共的逻辑分离开来,将子类的行为抽象为算法插入到公共的逻辑中,这样替换子类的行为也不会对公共逻辑产生影响,也不会影响到调用类的逻辑。

  

  下面是一个策略模式的简单例子,类图如下:

       

         公共逻辑Context的代码如下:

public class Context{
    public void contextInterface(){
    //add common code here
        strategy.strategyInterface();
    //add common code here
    }

    /**
     * @link aggregation
     * @directed 
     */
    private Strategy strategy;

    private void setStrategy (Strategy strategy){
    this.strategy = strategy;
    }

    private Strategy getStrategy (){
    return this.strategy;
    }
}

  子类算法的接口如下:

abstract public class Strategy{
    public abstract void strategyInterface();
}

  具体的算法如下:

public class ConcreteStrategy extends Strategy{
    public void strategyInterface(){
        //write you algorithm code here
    }
}

  当我们希望修改具体算法中的实现,我们只要重写一个类,继承Strategy接口,Context中的公共逻辑不需要修改。

 

      Java中策略模式的例子:

  环境角色由Container扮演,算法接口由LayoutManager扮演,具体算法由GridBagLayout、GridLayout等扮演。

  Container中的代码:    

if (layoutMgr != null) {
                if (layoutMgr instanceof LayoutManager2) {
                    ((LayoutManager2)layoutMgr).addLayoutComponent(comp, null);
                } else {
                    layoutMgr.addLayoutComponent(null, comp);
                }
            }

      GridBagLayout中的addLayoutComponent方法的代码:

    public void addLayoutComponent(Component comp, Object constraints) {
        if (constraints instanceof GridBagConstraints) {
            setConstraints(comp, (GridBagConstraints)constraints);
        } else if (constraints != null) {
            throw new IllegalArgumentException("cannot add to layout: constraints must be a GridBagConstraint");
        }
    }

  BorderLayout的addLayoutComponent方法的代码:

    public void addLayoutComponent(Component comp, Object constraints) {
      synchronized (comp.getTreeLock()) {
        if ((constraints == null) || (constraints instanceof String)) {
            addLayoutComponent((String)constraints, comp);
        } else {
            throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
        }
      }
    }

 

  还有一个很好的例子是系统要调用一种排序算法,可以是冒泡排序,快速排序等排序算法中的一种。应用策略模式可以很好的完成需求,并且维护性也很好。下面是类图:

  客户端在调用Sorter时根据实际的需求传入BinSort或是BubbleSort等,这个决定应该是客户端来做的。

      

       策略模式的优缺点如下:

       优点:1.公共的逻辑被抽取到环境类中,避免了重复代码。

                  2.策略模式提供了比继承更为灵活的方式,较模板方式的灵活性要更高,子类对抽象算法的实现可以是完全不同的。

                  3.使用策略模式可以避免使用多重的条件判断语句来做逻辑。

       缺点:1.客户端需要熟悉具体的算法子类以及自己需要调用哪一个算法子类。

                  2.策略模式可能会生成很多个的算法子类,可以使用享元模式来减少算法子类实例的个数。

 

posted on 2014-12-13 22:50  lnlvinso  阅读(891)  评论(0编辑  收藏  举报