Java設計模式(九)

rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> rel="themeData" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">

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.應付客戶改變需求,對於某應用需要採用新的方式,比如改變數據庫

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章