Java设计模式(九)

来源:互联网 发布:智能楼宇 知乎 编辑:程序博客网 时间:2024/04/29 08:55

Java设计模式(九)

------------策略模式

定义

定义一组策略算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。

实例

比如一级方程式中的赛车的轮胎,可以使用雨胎,干胎,中性胎;一个Swing 容器可以设定布局管理器,可以是FlowLayout,BorderLayout…;他们都可以动态相互替换,这些都是典型的策略模式。

用法概述

策略模式(Strategy)属于对象行为型设计模式,主要是定义一系列的策略算法,把这些算

法一个个封装成拥有共同接口的单独的类,并且使它们之间可以互换。策略模式使这些算法

在客户端调用它们的时候能够互不影响地变化。这里的算法不要狭义的理解为数据结构中算

法,可以理解为不同的业务处理方法。

这种做法会带来什么样的好处呢?

它将算法的使用和算法本身分离,即将变化的具体算法封装了起来,降低了代码的耦合

度,系统业务策略的更变仅需少量修改。算法被提取出来,这样可以使算法得到重用。

构造

我们延续上面Swing布局管理器的例子,我们这里就模拟一下它的实现,如果感兴趣可以参看JDK的源码。

角色

算法使用环境(Context)角色

通常是一个抽象实体和一组实现子类,在抽象类中定义一个抽象策略的引用,执行这个策略一般以方法的形式定义再在抽象类父中(因为父类并不关心使用的是什么策略),如果有默认策略我们应该在父类中进行指定。

 

public abstract class AbstractContainer {

       public String name = "";

       // 所有容器都具有的show功能

       public abstract void show();

       public LayoutStrategy layout;

 

       public LayoutStrategy getLayout() {

              return layout;

       }

 

       public void setLayout(LayoutStrategy layout) {

              this.layout = layout;

       }

 

       public void doLayout() {

              if (layout == null) {

                     layout = new BorderLayout();

              }

              layout.layout();

       }

 

}

 

 

public class MyFrame extends AbstractContainer {

       @Override

       public void show() {

              // TODO Auto-generated method stub

              layout = new BorderLayout();

              this.doLayout();

              System.out.println("我是一个自定义窗口");

       }

}

 

 

public class MyPanel extends AbstractContainer {

       @Override

       public void show() {

              // TODO Auto-generated method stub

              //layout=new FlowLayout();

              //this.setLayout(layout);

              this.doLayout();

              System.out.println("我是一个自定义面板");

       }

}

抽象策略(Strategy)角色

 

public interface LayoutStrategy {

       public void layout();

 

}

 

具体策略(Concrete Strategy)角色:

 

public class BorderLayout implements LayoutStrategy {

 

       @Override

       public void layout() {

              // TODO Auto-generated method stub

              System.out.println("我使用了BorderLayout布局管理器");

       }

 

}

 

public class FlowLayout implements LayoutStrategy {

 

       @Override

       public void layout() {

              // TODO Auto-generated method stub

              System.out.println("我使用了FlowLayout布局管理器");

       }

}

 

客户端代码:

 

public class MyTest {

       /**

        * @param args

        */

       public static void main(String[] args) {

              // TODO Auto-generated method stub

              AbstractContainer panel=new MyPanel();

              panel.show();

             

              AbstractContainer frame =new MyFrame();

              frame.show();

             

              //动态改变策略

              panel.setLayout(new FlowLayout());

              panel.show();

       }

}

 

打印结果:

         我使用了BorderLayout布局管理器

         我是一个自定义面板

         我使用了BorderLayout布局管理器

         我是一个自定义窗口

         我使用了FlowLayout布局管理器

         我是一个自定义面板

 

 

总结

下面是使用策略模式的一些建议:

1) 系统需要能够在几种算法中快速的切换

2) 系统中有一些类它们仅某些行为策略不同时(通常为拥有同一个父类的子类),可以考虑采用策略模式来进行重构。

3) 系统中存在多重条件选择语句时,可以考虑采用策略模式来重构。

但是要注意一点,策略模式中不可以同时使用多于一个的策略算法


我们为什么要使用策略模式,用继承不行吗?

继承的缺点:

1.代码在多个子类中重复

2.运行时的行为不容易改变

3.改变会牵一发动全身,造成其他子类不想要的改变。


策略模式优点:

1.方便增加新的处理方式(策略)

2.应付客户改变需求,对于某应用需要采用新的方式,比如改变数据库

 

 

原创粉丝点击