<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                31.1 代理模式VS裝飾模式 對于兩個模式,首先要說的是,裝飾模式就是代理模式的一個特殊應用,兩者的共同點是都具有相同的接口,不同點則是代理模式著重對代理過程的控制,而裝飾模式則是對類的功能進行加強或減弱,它著重類的功能變化,我們舉例來說明它們的區別。 31.1.1 代理模式 一個著名的短跑運動員有自己的代理人。如果你很仰慕他,你找運動員說“你跑個我看看”,運動員肯定不搭理你,不過你找到他的代理人就不一樣了,你可能和代理人比較熟,可以稱兄道弟,這個忙代理人還是可以幫的,于是代理人同意讓你欣賞運動員的練習賽,這對你來說已經是莫大的榮耀了。我們來看類圖,如圖31-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036d31ccd.jpg) 圖31-1 運動員跑步 這是一個套用代理模式的簡單應用,非常簡單!一個對象,然后再是自己的代理。我們先來看一下代碼,先看抽象主題類,如代碼清單31-1所示。 代碼清單31-1 抽象運動員 public?interface?IRunner?{ ?????//運動員的主要工作就是跑步 ?????public?void?run(); } 一個具體的短跑運動員跑步是很瀟灑的,如代碼清單31-2所示。 代碼清單31-2 運動員跑步 public?class?Runner?implements?IRunner?{ ?????public?void?run()?{ ?????????????System.out.println("運動員跑步:動作很瀟灑"); ?????} } 看看現在的明星運動員,一般都有自己的代理人,要么是專職的,要么就是自己的教練兼職,那我們來看看代理人的職責,如代碼清單31-3所示。 代碼清單31-3 代理人 public?class?RunnerAgent?implements?IRunner?{ ?????private?IRunner?runner; ?????public?RunnerAgent(IRunner?_runner){ ?????????????this.runner?=?_runner; ?????} ?????//代理人是不會跑的 ?????public?void?run()?{ ?????????????Random?rand?=?new?Random(); ?????????????if(rand.nextBoolean()){ ?????????????????????System.out.println("代理人同意安排運動員跑步"); ?????????????????????runner.run(); ?????????????}else{ ?????????????????????System.out.println("代理人心情不好,不安排運動員跑步"); ??????????} ?????} } 我們只是定義了一個代理人,并沒有明確定義是哪一個運動員的代理,需要在運行時指定被代理者,而且我們還在代理人的run方法中做了判斷,想讓被代理人跑步就跑步,不樂意就拒絕,對于主題類的行為是否可以發生,代理類有絕對的控制權。我們編寫一個場景類來模擬這種情況,如代碼清單31-4所示。 代碼清單31-4 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//定義一個短跑運動員 ?????????????IRunner?liu?=?new?Runner(); ?????????????//定義liu的代理人 ?????????????IRunner?agent?=?new?RunnerAgent(liu); ?????????????//要求運動員跑步 ?????????????System.out.println("====客人找到運動員的代理要求其去跑步==="); ?????????????agent.run(); ?????} } 由于我們使用了隨機數產生模擬結果,因此運行結果有兩種可能情況,第一種情況如下所示: ====客人找到運動員的代理要求其去跑步=== 代理人同意安排運動員跑步 運動員跑步:動作很瀟灑 運行結果的第二種情況如下所示: ====客人找到運動員的代理要求其去跑步=== 代理人心情不好,不安排運動員跑步 不管是哪種情況,我們都證實了代理的一個功能:在不改變接口的前提下,對過程進行控制。在我們例子中,運動員要不要跑步是由代理人決定的,代理人說跑步就跑步,說不跑就不跑,它有絕對判斷權。 31.1.2 裝飾模式 如果使用裝飾模式,我們該怎么實現這個過程呢?裝飾模式是對類功能的加強,怎么加強呢?增強跑步速度!在屁股后面安裝一個噴氣動力裝置,類似火箭的噴氣裝置,那速度變得很快,《蜘蛛俠》中的那個反面角色不就是這樣的嗎?好,我們來看類圖,如圖31-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036d46e32.jpg) 圖31-2 增強運動員的功能 很驚訝?這個代理模式完全一樣的類圖?是的,完全一樣!不過其實現的意圖卻不同,我們先來看代碼,IRunner和Runner與代理模式相同,詳見代碼清單31-1和代碼清單31-2所示,在此不再贅述。我們來看裝飾類RunnerWithJet,如代碼清單31-5所示。 代碼清單31-5 裝飾類 public?class?RunnerWithJet?implements?IRunner?{ ?????private?IRunner?runner; ?????public?RunnerWithJet(IRunner?_runner){ ?????????????this.runner?=?_runner; ?????} ?????public?void?run()?{ ?????????????System.out.println("加快運動員的速度:為運動員增加噴氣裝置"); ?????????????runner.run(); ?????} } 這和代理模式中的代理類也是非常相似的,只是裝飾類對類的行為沒有決定權,只有增強作用,也就是說它不決定被代理的方法是否執行,它只是再次增加被代理的功能。我們來看場景類,如代碼清單31-6所示。 代碼清單31-6 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//定義運動員 ?????????????IRunner?liu?=?new?Runner(); ?????????????//對其功能加強 ?????????????liu?=?new?RunnerWithJet(liu); ?????????????//看看它的跑步情況如何 ?????????????System.out.println("===增強后的運動員的功能==="); ?????????????liu.run(); ?????} } 運行結果如下所示: ===增強后的運動員的功能=== 加快運動員的速度:為運動員增加噴氣裝置 運動員跑步:動作很瀟灑 注意思考一下我們的程序,我們通過增加了一個裝飾類,就完成了對原有類的功能增加,由一個普通的短跑運動員變成了帶有噴氣裝置的超人運動員,其速度豈是普通人能相比的?! 31.1.3 最佳實踐 通過例子,我們可以看出代理模式和裝飾模式有非常相似的地方,甚至代碼實現都非常相似,特別是裝飾模式中省略抽象裝飾角色后,兩者代碼基本上相同,但是還是有細微的差別。 代理模式是把當前的行為或功能委托給其他對象執行,代理類負責接口限定:是否可以調用真實角色,以及是否對發送到真實角色的消息進行變形處理,它不對被主題角色(也就是被代理類)的功能做任何處理,保證原汁原味的調用。代理模式使用到極致開發就是AOP,這是各位采用Spring架構開發必然要使用到的技術,它就是使用了代理和反射的技術。 裝飾模式是在要保證接口不變的情況下加強類的功能,它保證的是被修飾的對象功能比原始對象豐富(當然,也可以減弱),但不做準入條件判斷和準入參數過濾,如是否可以執行類的功能,過濾輸入參數是否合規等,這不是裝飾模式關心的。 代理模式在Java的開發中俯拾皆是,是大家非常熟悉的模式,應用非常廣泛,而裝飾模式是一個比較拘謹的模式,在實際應用中接觸比較少,但是也有不少框架項目使用了裝飾模式,例如在JDK的java.io.*包中就大量使用裝飾模式,類似如下的代碼: OutputStream?out?=?new?DataOutputStream(new?FileOutputStream("test.txt")) 這是裝飾模式的一個典型應用,使用DataOutputStream封裝了一個FileOutputStream,以方便進行輸出流處理。
                  <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>

                              哎呀哎呀视频在线观看