細心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

          BlogJava 聯系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          考慮您要設計一個更換各種符號的工具類TextCharChange,您是否會採用這樣的方式:
          public void replace() {
             switch(getChangeType()) {
                case RN_TYPE:   replaceRN();
                                    break;
                case N_TYPE: replaceN();
                                    break;
                case OTHER_TYPE: replaceOTHER():
                                    break;
                ...
             }
          }
           
          這麼作的缺點是,日後您要增加更換符號的策略時,會有幾個地方需要修改:增加TYPE常數、增加TextCharChange中的 replaceXXX()方法、增加 replace()方法中的switch case判斷。

          像這種策略採用的情況,可以將策略加以封裝為一個物件,而不是將策略寫死在某個類中,如此一來,策略可以獨立於客戶端,隨時增加變化、增加或減少策略,即使是修改每個策略的內容,也不會對客戶端程式造成影響。

          來舉個最簡單的例子,首先要知道Windows與Linux的文字檔案換行符號是不同的,Windows是 /r/n ,而Linux是 /n,今天您要設計一個文字編輯器,在適當的時候,您必須要能隨時轉換這兩種符號,如果不採用上面的策略採用流程的話,要如何設計:
          • TextStrategy.java
          public abstract class TextStrategy { 
          protected String text;

          public TextStrategy(String text) {
          this.text = text;
          }

          public abstract String replace();
          }

          • LinuxStrategy.java
          public class LinuxStrategy extends TextStrategy { 
          public LinuxStrategy(String text) {
          super(text);
          }

          public String replace() {
          preOperation();
          System.out.println(
          text = text.replaceAll("@r@n", "@n"));
          postOperation();

          return text;
          }

          private void preOperation() {
          System.out.println("LinuxStrategy preOperation");
          }

          private void postOperation() {
          System.out.println("LinuxStrategy postOperation");
          }
          }

          • WindowsStrategy.java
          public class WindowsStrategy extends TextStrategy { 
          public WindowsStrategy(String text) {
          super(text);
          }

          public String replace() {
          startOperation();
          System.out.println(
          text = text.replaceAll("@n", "@r@n"));
          endOperation();

          return text;
          }

          private void startOperation() {
          System.out.println("WindowsStrategy startOperation");
          }

          private void endOperation() {
          System.out.println("WindowsStrategy endOperation");
          }
          }

          • TextCharChange.java
          public class TextCharChange { 
          public static void replace(TextStrategy strategy) {
          strategy.replace();
          }
          }

          • Main.java
          public class Main { 
          public static void main(String[] args) {
          String linuxText =
          "This is a test text!!@n Oh! Line Return!!@n";
          String windowsText =
          "This is a test text!!@r@n Oh! Line Return@r@n";

          // load file, suppose it's Linux's text file
          // take the WindowsStrategy
          // I want to change it to Windows' text file
          TextCharChange.replace(
          new WindowsStrategy(linuxText));

          // such-and-such operation.....
          System.out.println();

          // load file, suppose it's Windows' text file
          // take the LinuxStrategy
          // I want to change it to Linux's text file
          TextCharChange.replace(
          new LinuxStrategy(windowsText));
          }
          }

          為了明顯的秀出結果,我們使用@n來表示 '/n' , @r 表示 '/r' 符號,Main中的流程是個假設的情況,何時採用何種策略是隨機的。

          在Strategy模式中,使用一個公開的介面replace(),讓客戶端請求,而在實作replace()時,可以任意的組合演算策略,程式中的 preOperation()、postOperation()就是用以示意演算的組合概念,Strategy模式封裝了這些演算過程,使它們易於組合、修改、替換,上面這個例子的UML 類別結構圖如下所示:
          Strategy

          Strategy模式的UML類別結構圖如下:
          Strategy
          從行為上來說,State 模式 與Strategy模式是蠻相近的。

          State模式:看當前是什麼狀態,就採取什麼動作。

          Strategy模式:看需求(情境)是什麼,採用適當的策略。

          不過兩者雖相似,應用的場合稍有不同,State模式中有一個重點在於設定狀態變化,就像 Gof 例子中舉的TCP連線;Strategy策略模式則是直接採用適當的策略的感覺,例如Gof中說的,採用適當的演算法來作正文換行。
          posted on 2007-04-17 10:52 張金鵬 閱讀(212) 評論(0)  編輯  收藏 所屬分類: Behavioral 模式
          主站蜘蛛池模板: 汝城县| 渭源县| 从化市| 诏安县| 习水县| 南和县| 梅河口市| 嫩江县| 吉木乃县| 广东省| 平凉市| 天水市| 黔南| 安义县| 天峻县| 莱州市| 德钦县| 清远市| 垣曲县| 武穴市| 西乡县| 汶上县| 云南省| 宿州市| 邹平县| 黎平县| 麦盖提县| 鄂托克前旗| 武山县| 韩城市| 无锡市| 湖州市| 莱芜市| 汤原县| 鲁山县| 灵丘县| 论坛| 巴东县| 黑河市| 凭祥市| 牡丹江市|