<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                第16章 責任鏈模式 16.1 古代婦女的枷鎖——“三從四德” 中國古代對婦女制定了“三從四德”的道德規范,“三從”是指“未嫁從父、既嫁從夫、夫死從子”。也就是說,一位女性在結婚之前要聽從于父親,結婚之后要聽從于丈夫,如果丈夫死了還要聽從于兒子。舉例來說,如果一位女性要出去逛街,在她出嫁前必須征得父親的同意,出嫁之后必須獲得丈夫的許可,那丈夫死了怎么辦?那就得問問兒子是否允許自己出去逛街。估計你接下來馬上要問:“要是沒有兒子怎么辦?”那就請示小叔子、侄子等。在父系社會中,婦女只占從屬地位,現在想想中國古代的婦女還是挺悲慘的,連逛街都要多番請示。作為父親、丈夫或兒子,只有兩種選擇:要不承擔起責任來,允許她或不允許她逛街;要不就讓她請示下一個人,這是整個社會體系的約束,應用到我們項目中就是業務規則。下面來看如何通過程序來實現“三從”,需求很簡單:通過程序描述一下古代婦女的“三從”制度。好,我們先來看類圖,如圖16-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b003649ba88.jpg) 圖16-1 婦女“三從”類圖 類圖非常簡單,IHandler是三個有決策權對象的接口,IWomen是女性的代碼,其實現也非常簡單,IWomen如代碼清單16-1所示。 代碼清單16-1 女性接口 public?interface?IWomen?{ ?????//獲得個人狀況 ?????public?int?getType(); ?????//獲得個人請示,你要干什么?出去逛街?約會?還是看電影? ?????public?String?getRequest(); } 女性接口僅兩個方法,一個是取得當前的個人狀況getType,通過返回值決定是結婚了還是沒結婚、丈夫是否在世等,另外一個方法getRequest是要請示的內容,要出去逛街還是吃飯,其實現類如代碼清單16-2所示。 代碼清單16-2 古代婦女 public?class?Women?implements?IWomen{ ?????/* ??????*?通過一個int類型的參數來描述婦女的個人狀況 ??????*?1--未出嫁 ??????*?2--出嫁 ??????*?3--夫死 ??????*/ ?????private?int?type=0; ?????//婦女的請示 ?????private?String?request?=?""; ?????//構造函數傳遞過來請求 ?????public?Women(int?_type,String?_request){ ?????????????this.type?=?_type; ?????????????this.request?=?_request; ?????} ?????//獲得自己的狀況 ?????public?int?getType(){ ?????????????return?this.type; ?????} ?????//獲得婦女的請求 ?????public?String?getRequest(){ ?????????????return?this.request; ?????} } 我們使用數字來代表女性的不同狀態:1是未結婚;2是已經結婚的,而且丈夫健在;3是丈夫去世了。從整個設計上分析,有處理權的人(如父親、丈夫、兒子)才是設計的核心,他們是要處理這些請求的,我們來看有處理權的人員接口IHandler,如代碼清單16-3所示。 代碼清單16-3 有處理權的人員接口 public?interface?IHandler?{ ?????//一個女性(女兒、妻子或者母親)要求逛街,你要處理這個請求 ?????public?void?HandleMessage(IWomen?women); } 非常簡單,有處理權的人對婦女的請求進行處理,分別有三個實現類,在女兒沒有出嫁之前父親是有決定權的,其實現類如代碼清單16-4所示。 代碼清單16-4 父親類 public?class?Father?implements?IHandler?{ ?????//未出嫁的女兒來請示父親 ?????public?void?HandleMessage(IWomen?women)?{ ?????????????System.out.println("女兒的請示是:"+women.getRequest()); ?????????????System.out.println("父親的答復是:同意"); ?????} } 在女性出嫁后,丈夫有決定權,如代碼清單16-5所示。 代碼清單16-5 丈夫類 public?class?Husband?implements?IHandler?{ ?????//妻子向丈夫請示 ?????public?void?HandleMessage(IWomen?women)?{ ?????????????System.out.println("妻子的請示是:"+women.getRequest()); ?????????????System.out.println("丈夫的答復是:同意"); ?????} } 在女性喪偶后,對母親提出的請求兒子有決定權,如代碼清單16-6所示。 代碼清單16-6 兒子類 public?class?Son?implements?IHandler?{ ?????//母親向兒子請示 ?????public?void?HandleMessage(IWomen?women)?{ ?????????????System.out.println("母親的請示是:"+women.getRequest()); ?????????????System.out.println("兒子的答復是:同意"); ?????} } 以上三個實現類非常簡單,只有一個方法,處理女兒、妻子、母親提出的請求,我們來模擬一下一個古代婦女出去逛街是如何請示的,如代碼清單16-7所示。 代碼清單16-7 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//隨機挑選幾個女性 ?????????????Random?rand?=?new?Random(); ?????????????ArrayList<IWomen>?arrayList?=?new?ArrayList(); ?????????????for(int?i=0;i<5;i++){ ?????????????????????arrayList.add(new?Women(rand.nextInt(4),"我要出去逛街")); ?????????????} ?????????????//定義三個請示對象 ?????????????IHandler?father?=?new?Father(); ?????????????IHandler?husband?=?new?Husband(); ?????????????IHandler?son?=?new?Son(); ?????????????for(IWomen?women:arrayList){ ?????????????????????if(women.getType()?==1){?//未結婚少女,請示父親 ????????????????????????????System.out.println("\n--------女兒向父親請示-------"); ????????????????????????????father.HandleMessage(women); ?????????????????????}else?if(women.getType()?==2){??//已婚少婦,請示丈夫 ????????????????????????????System.out.println("\n--------妻子向丈夫請示-------"); ????????????????????????????husband.HandleMessage(women); ?????????????????????}else?if(women.getType()?==?3){?//母親請示兒子 ????????????????????????????System.out.println("\n--------母親向兒子請示-------"); ????????????????????????????son.HandleMessage(women); ?????????????????????}else{ ????????????????????????????//暫時什么也不做 ?????????????????????} ?????????????} ?????} } 首先是通過隨機方法產生了5個古代婦女的對象,然后看她們是如何就逛街這件事去請示的,運行結果如下所示(由于是隨機的,您看到的結果可能和這里有所不同): --------女兒向父親請示------- 女兒的請示是:我要出去逛街 父親的答復是:同意 --------母親向兒子請示------- 母親的請示是:我要出去逛街 兒子的答復是:同意 --------妻子向丈夫請示------- 妻子的請示是:我要出去逛街 丈夫的答復是:同意 --------女兒向父親請示------- 女兒的請示是:我要出去逛街 父親的答復是:同意 “三從四德”的舊社會規范已經完整地表現出來了,你看誰向誰請示都定義出來了,但是你是不是發現這個程序寫得有點不舒服?有點別扭?有點想重構它的感覺?那就對了!這段代碼有以下幾個問題: ● 職責界定不清晰 對女兒提出的請示,應該在父親類中做出決定,父親有責任、有義務處理女兒的請示,因此Father類應該是知道女兒的請求自己處理,而不是在Client類中進行組裝出來,也就是說原本應該是父親這個類做的事情拋給了其他類進行處理,不應該是這樣的。 ● 代碼臃腫 我們在Client類中寫了if...else的判斷條件,而且能隨著能處理該類型的請示人員越多,if...else的判斷就越多,想想看,臃腫的條件判斷還怎么有可讀性?! ● 耦合過重 這是什么意思呢,我們要根據Women的type來決定使用IHandler的那個實現類來處理請求。有一個問題是:如果IHandler的實現類繼續擴展怎么辦?修改Client類?與開閉原則違背了! ● 異常情況欠考慮 妻子只能向丈夫請示嗎?如果妻子(比如一個現代女性穿越到古代了,不懂什么“三從四德”)向自己的父親請示了,父親應該做何處理?我們的程序上可沒有體現出來,邏輯失敗了! 既然有這么多的問題,那我們要想辦法來解決這些問題,我們先來分析一下需求,女性提出一個請示,必然要獲得一個答復,甭管是同意還是不同意,總之是要一個答復的,而且這個答復是唯一的,不能說是父親作出一個決斷,而丈夫也作出了一個決斷,也即是請示傳遞出去,必然有一個唯一的處理人給出唯一的答復,OK,分析完畢,收工,重新設計,我們可以抽象成這樣一個結構,女性的請求先發送到父親類,父親類一看是自己要處理的,就作出回應處理,如果女兒已經出嫁了,那就要把這個請求轉發到女婿來處理,那女婿一旦去天國報道了,那就由兒子來處理這個請求,類似于如圖16-2所示的順序處理圖。 ![](https://box.kancloud.cn/2016-08-14_57b00364b141a.jpg) 圖16-2 女性請示的順序處理圖 父親、丈夫、兒子每個節點有兩個選擇:要么承擔責任,做出回應;要么把請求轉發到后序環節。結構分析得已經很清楚了,那我們看怎么來實現這個功能,類圖重新修正,如圖16-3所示。 ![](https://box.kancloud.cn/2016-08-14_57b00364c8cd3.jpg) 圖16-3 順序處理的類圖 從類圖上看,三個實現類Father、Husband、Son只要實現構造函數和父類中的抽象方法response就可以了,具體由誰處理女性提出的請求,都已經轉移到了Handler抽象類中,我們來看Handler怎么實現,如代碼清單16-8所示。 代碼清單16-8 修改后的Handler類 public?abstract?class?Handler?{ ?????public?final?static?int?FATHER_LEVEL_REQUEST?=?1; ?????public?final?static??int?HUSBAND_LEVEL_REQUEST?=?2; ?????public?final?static??int?SON_LEVEL_REQUEST?=?3; ?????//能處理的級別 ?????private?int?level?=0;?????? ?????//責任傳遞,下一個人責任人是誰 ?????private?Handler?nextHandler; ?????//每個類都要說明一下自己能處理哪些請求 ?????public?Handler(int?_level){ ?????????????this.level?=?_level; ?????} ?????//一個女性(女兒、妻子或者是母親)要求逛街,你要處理這個請求 ?????public?final?void?HandleMessage(IWomen?women){ ?????????????if(women.getType()?==?this.level){ ????????????????????this.response(women); ?????????????}else{ ????????????????????if(this.nextHandler?!=?null){??//有后續環節,才把請求往后遞送 ??????????????????????????this.nextHandler.HandleMessage(women); ????????????????????}else{?//已經沒有后續處理人了,不用處理了 ??????????????????????????System.out.println("---沒地方請示了,按不同意處理---\n"); ????????????????????} ?????????????} ?????} ?????/* ??????*?如果不屬于你處理的請求,你應該讓她找下一個環節的人,如女兒出嫁了, ??????*?還向父親請示是否可以逛街,那父親就應該告訴女兒,應該找丈夫請示 ??????*/ ?????public?void?setNext(Handler?_handler){ ?????????????this.nextHandler?=?_handler; ?????} ?????//有請示那當然要回應 ?????protected?abstract?void?response(IWomen?women); } 方法比較長,但是還是比較簡單的,讀者有沒有看到,其實在這里也用到模板方法模式,在模板方法中判斷請求的級別和當前能夠處理的級別,如果相同則調用基本方法,做出反饋;如果不相等,則傳遞到下一個環節,由下一環節做出回應,如果已經達到環節結尾,則直接做不同意處理。基本方法response需要各個實現類實現,每個實現類只要實現兩個職責:一是定義自己能夠處理的等級級別;二是對請求做出回應,我們首先來看首節點Father類,如代碼清單16-9所示。 代碼清單16-9 父親類 public?class?Father?extends?Handler?{ ?????//父親只處理女兒的請求 ?????public?Father(){ ?????????????super(Handler.FATHER_LEVEL_REQUEST); ?????} ?????//父親的答復 ?????protected?void?response(IWomen?women)?{ ?????????????System.out.println("--------女兒向父親請示-------"); ?????????????System.out.println(women.getRequest()); ?????????????System.out.println("父親的答復是:同意\n"); ?????} } 丈夫類定義自己能處理的等級為2的請示,如代碼清單16-10所示。 代碼清單16-10 丈夫類 public?class?Husband?extends?Handler?{ ?????//丈夫只處理妻子的請求 ?????public?Husband(){ ?????????????super(Handler.HUSBAND_LEVEL_REQUEST); ?????} ?????//丈夫請示的答復 ?????protected?void?response(IWomen?women)?{ ?????????????System.out.println("--------妻子向丈夫請示-------"); ?????????????System.out.println(women.getRequest()); ?????????????System.out.println("丈夫的答復是:同意\n"); ?????} } 兒子類只能處理等級為3的請示,如代碼清單16-11所示。 代碼清單16-11 兒子類 public?class?Son?extends?Handler?{ ?????//兒子只處理母親的請求 ?????public?Son(){ ?????????????super(Handler.SON_LEVEL_REQUEST); ?????} ?????//兒子的答復 ?????protected?void?response(IWomen?women)?{ ?????????????System.out.println("--------母親向兒子請示-------"); ?????????????System.out.println(women.getRequest()); ?????????????System.out.println("兒子的答復是:同意\n"); ?????} } 這三個類都很簡單,構造方法是必須實現的,父類框定子類必須有一個顯式構造函數,子類不實現編譯不通過。通過構造方法我們設置了各個類能處理的請求類型,Father只能處理請求類型為1(也就是女兒)的請求;Husband只能處理請求類型類為2(也就是妻子)的請求,兒子只能處理請求類型為3(也就是母親)的請求,那如果請求類型為4的該如何處理呢?在Handler中我們已經判斷了,如何沒有相應的處理者(也就是沒有下一環節),則視為不同意。 Women類的接口沒有任何變化,請參考圖16-1所示。 實現類稍微有些變化,如代碼清單16-12所示。 代碼清單16-12 女性類 public?class?Women?implements?IWomen{ ?????/* ??????*?通過一個int類型的參數來描述婦女的個人狀況 ??????*?1--未出嫁 ??????*?2--出嫁 ??????*?3--夫死 ??????*/ ?????private?int?type=0; ?????//婦女的請示 ?????private?String?request?=?""; ?????//構造函數傳遞過來請求 ?????public?Women(int?_type,String?_request){ ?????????????this.type?=?_type;????????? ?????????????//為了便于顯示,在這里做了點處理 ?????????????switch(this.type){ ?????????????case?1: ?????????????????????????this.request?=?"女兒的請求是:"?+?_request; ?????????????????????????break; ?????????????case?2: ?????????????????????????this.request?=?"妻子的請求是:"?+?_request; ?????????????????????????break; ?????????????case?3: ?????????????????????????this.request?=?"母親的請求是:"?+?_request; ?????????????} ?????} ?????//獲得自己的狀況 ?????public?int?getType(){ ?????????????return?this.type; ?????} ?????//獲得婦女的請求 ?????public?String?getRequest(){ ?????????????return?this.request; ?????} } 為了展示結果清晰一點,Women類做了一些改變,如粗體部分所示。我們再來看Client類是怎么描述古代這一個禮節的,如代碼清單16-13所示。 代碼清單16-13 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//隨機挑選幾個女性 ?????????????Random?rand?=?new?Random(); ?????????????ArrayList<IWomen>?arrayList?=?new?ArrayList(); ?????????????for(int?i=0;i<5;i++){ ????????????????????arrayList.add(new?Women(rand.nextInt(4),"我要出去逛街")); ?????????????} ?????????????//定義三個請示對象 ?????????????Handler?father?=?new?Father(); ?????????????Handler?husband?=?new?Husband(); ?????????????Handler?son?=?new?Son(); ?????????????//設置請示順序 ?????????????father.setNext(husband); ?????????????husband.setNext(son); ?????????????for(IWomen?women:arrayList){ ????????????????????father.HandleMessage(women); ?????????????} ?????} } 在Client中設置請求的傳遞順序,先向父親請示,不是父親應該解決的問題,則由父親傳遞到丈夫類解決,若不是丈夫類解決的問題則傳遞到兒子類解決,最終的結果必然有一個返回,其運行結果如下所示。 --------妻子向丈夫請示------- 妻子的請求是:我要出去逛街 丈夫的答復是:同意 --------女兒向父親請示------- 女兒的請求是:我要出去逛街 父親的答復是:同意 --------母親向兒子請示------- 母親的請求是:我要出去逛街 兒子的答復是:同意 --------妻子向丈夫請示------- 妻子的請求是:我要出去逛街 丈夫的答復是:同意 --------母親向兒子請示------- 母親的請求是:我要出去逛街 兒子的答復是:同意 結果也正確,業務調用類Client也不用去做判斷到底是需要誰去處理,而且Handler抽象類的子類可以繼續增加下去,只需要擴展傳遞鏈而已,調用類可以不用了解變化過程,甚至是誰在處理這個請求都不用知道。在這種模式下,即使現代社會的一個小太妹穿越到古代(例如掉入時空隧道,或者時空突然扭轉,甚至是突然魔法顯靈),對“三從四德”沒有任何了解也可以自由地應付,反正只要請示父親就可以了,該父親處理就父親處理,不該父親處理就往下傳遞。這就是責任鏈模式。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看