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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                第17章 裝飾模式 17.1 罪惡的成績單 “中庸”是中國儒教文化的集中體現,說話或做事情都不能太直接,需要有技巧。比如談話,如果你要批評某個人,你不能一上來就說他這做得不對,那也做得不對,你要先肯定他的成績,表揚一下優點;然后再指出不足,指出錯誤的地方,最后再來點激勵,你修改了這些缺點后有哪些好處,比如你能帶更多的小兵、升職等。如果你一上來就是一頓批評,你瞅瞅看,對方肯定是不服氣,甚至是頂撞你說:“此處不養爺,自有養爺處”,于是甩門而去。 這是說話,做事情也是一樣。在山寨產品流行之前,假貨也是比較“盛行”的。本人2002年買了一部手機,當時老板吹得天花亂墜,承諾這部手機是最新的,我看著也像,殼子是嶄新的,包裝是嶄新的,沒有任何瑕疵,就是比正品便宜了很多,于是我買了,因為缺錢啊!用了3個月,壞了,送修檢查,結果診斷出這是新殼裝舊機,我暈!拿一部舊手機的線路板,找個新的外殼、屏幕、包裝就成了新手機,害人不淺啊! 我們不說不開心的事情,今天以什么例子為開場白呢?就說說我上小學的糗事吧。我上小學的時候學習成績非常差,班級上有40多個同學,我基本上都是排在45名以后,按照老師給我的評價就是:“不是讀書的料”。但是我父親管得很嚴格,明知道我不是這塊料,還是“趕鴨子上架”,每次考完試我都戰戰兢兢,“竹筍炒肉”是肯定少不了的,但是能少點就少點吧,因為肉可是自己的。四年級期末考試考完,學校出來個很損的招兒(這招兒現在很流行的),打印出成績單,要家長簽字,然后才能上五年級,我那個恐懼呀,不過也就是幾秒鐘的時間,玩起來什么都忘記了。我們做架構,做設計,任何值得我們回憶的事件都可以通過設計記錄下來。當然了,這份成績單的事情也是可以通過類圖表示的,如圖17-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b00365252a9.jpg) 圖17-1 成績單類圖 成績單的抽象類,然后有一個四年級的成績單實現類,So Easy,我們先來看抽象類,如代碼清單17-1所示。 代碼清單17-1 抽象成績單 public?abstract?class?SchoolReport?{ ?????//成績單主要展示的就是你的成績情況 ?????public?abstract?void?report();????? ?????//成績單要家長簽字,這個是最要命的 ?????public?abstract?void?sign(); } 有抽象類了,我們再來看看具體的四年級成績單FouthGradeSchoolReport,如代碼清單17-2所示。 代碼清單17-2 四年級成績單 public?class?FouthGradeSchoolReport?extends?SchoolReport?{ ?????//我的成績單 ?????public?void?report()?{ ?????????????//成績單的格式是這個樣子的 ?????????????System.out.println("尊敬的XXX家長:");?? ?????????????System.out.println("??......"); ?????????????System.out.println("??語文?62??數學65?體育?98??自然??63"); ?????????????System.out.println("??......."); ?????????????System.out.println("???????????????家長簽名:???????"); ?????} ?????//家長簽名 ?????public?void?sign(String?name)?{ ?????????????System.out.println("家長簽名為:"+name); ?????} } 成績單出來,你別看什么62、65之類的成績,你要知道,在小學低于90分基本上就是中下等了,悲哀呀,愛學習的人咋就那么多!怎么著,那我把這個成績單給老爸看看?好,我們修改一下類圖,成績單給老爸看,如圖17-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b003653a9d4.jpg) 圖17-2 老爸查看成績單類圖 老爸開始看成績單,這個成績單可是最真實的,啥都沒有動過,原裝,Father類如代碼清單17-3所示。 代碼清單17-3 老爸查看成績單 public?class?Father?{ ?????public?static?void?main(String[]?args)?{ ?????????????//把成績單拿過來 ?????????????SchoolReport?sr?=?new?FouthGradeSchoolReport(); ?????????????//看成績單 ?????????????sr.report(); ?????????????//簽名?休想! ?????} } 運行結果如下: 尊敬的XXX家長: ...... 語文 62 數學65 體育 98 自然 63 .......        家長簽名: 就這成績還要我簽字?!老爸就開始找掃帚,我開始做準備:深呼吸,繃緊肌肉,提臀收腹。哈哈,幸運的是,這個不是當時的真實情況,我沒有直接把成績單交給老爸,而是在交給他之前做了點技術工作,我要把成績單封裝一下,封裝分類兩步來實現,如下所示。 ● 匯報最高成績 跟老爸說各個科目的最高分,語文最高是75,數學是78,自然是80,然后老爸覺得我的成績與最高分數相差不多,考的還是不錯的嘛!這個是實情,但是不知道是什么原因,反正期末考試都考得不怎么樣,但是基本上都集中在70分以上,我這60多分基本上還是墊底的角色。 ● 匯報排名情況 在老爸看完成績單后,告訴他我在全班排第38名,這個也是實情,為啥呢?有將近十個同學退學了!這個情況我是不會說的。不知道是不是當時第一次發成績單時學校沒有考慮清楚,沒有寫上總共有多少同學,排第幾名,反正是被我鉆了個空子。 那修飾是說完了,我們看看類圖如何修改,如圖17-3所示。 ![](https://box.kancloud.cn/2016-08-14_57b003654fc2d.jpg) 圖17-3 修飾成績單 我想這是大家最容易想到的類圖,通過直接增加了一個子類,重寫report方法,很容易地解決了這個問題,是不是這樣?是的,這確實是一個比較好的辦法,我們來看具體的實現,如代碼清單17-4所示。 代碼清單17-4 修飾成績單 public?class?SugarFouthGradeSchoolReport?extends?FouthGradeSchoolReport?{ ?????//首先要定義你要美化的方法,先給老爸說學校最高成績 ?????private?void?reportHighScore(){ ?????????????System.out.println("這次考試語文最高是75,數學是78,自然是80"); ?????} ?????//在老爸看完畢成績單后,我再匯報學校的排名情況 ?????private?void?reportSort(){ ?????????????System.out.println("我是排名第38名..."); ?????} ?????//由于匯報的內容已經發生變更,那所以要重寫父類 ?????@Override ?????public?void?report(){ ?????????????this.reportHighScore();??//先說最高成績 ?????????????super.report();??//然后老爸看成績單 ?????????????this.reportSort();?//然后告訴老爸學習學校排名 ?????} } 然后對Father類稍做修改就可以看到美化后的成績單,如代碼清單17-5所示。 代碼清單17-5 老爸查看修飾后的成績單 public?class?Father?{ ?????public?static?void?main(String[]?args)?{ ?????????????//把美化過的成績單拿過來 ?????????????SchoolReport?sr=?new?SugarFouthGradeSchoolReport(); ?????????????//看成績單 ?????????????sr.report(); ?????????????//然后老爸,一看,很開心,就簽名了 ?????????????sr.sign("老三");??//我叫小三,老爸當然叫老三 ?????} } 運行結果如下所示: 這次考試語文最高是75,數學是78,自然是80 尊敬的XXX家長: ...... 語文 62 數學65 體育 98 自然 63 .......         家長簽名: 我是排名第38名... 家長簽名為:老三 通過繼承確實能夠解決這個問題,老爸看成績單很開心,然后就給簽字了,但現實的情況是很復雜的,可能老爸聽我匯報最高成績后,就直接樂開花了,直接簽名了,后面的排名就沒必要看了,或者老爸要先看排名情況,那怎么辦?繼續擴展?你能擴展多少個類?這還是一個比較簡單的場景,一旦需要裝飾的條件非常多,比如20個,你還通過繼承來解決,你想象的子類有多少個?你是不是馬上就要崩潰了! 好,你也看到通過繼承情況確實出現了問題,類爆炸,類的數量激增,光寫這些類不累死你才怪,而且還要想想以后維護怎么辦,誰愿意接收這么一大攤本質相似的代碼維護工作?并且在面向對象的設計中,如果超過兩層繼承,你就應該想想是不是出設計問題了,是不是應該重新找一條康莊大道了,這是經驗值,不是什么絕對的,繼承層次越多以后的維護成本越多,問題這么多,那怎么辦?好辦,我們定義一批專門負責裝飾的類,然后根據實際情況來決定是否需要進行裝飾,類圖稍做修正,如圖17-4所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036564b76.jpg) 圖17-4 增加專門的裝飾類圖 增加一個抽象類和兩個實現類,其中Decorator的作用是封裝SchoolReport類,如果大家還記得代理模式,那么很容易看懂這個類圖,裝飾類的作用也就是一個特殊的代理類,真實的執行者還是被代理的角色FouthGradeSchoolReport,如代碼清單17-6所示。 代碼清單17-6 修飾的抽象類 public?abstract?class?Decorator?extends?SchoolReport{ ?????//首先我要知道是哪個成績單 ?????private?SchoolReport?sr; ?????//構造函數,傳遞成績單過來 ?????public?Decorator(SchoolReport?sr){ ?????????????this.sr?=?sr; ?????} ?????//成績單還是要被看到的 ?????public?void?report(){ ?????????????this.sr.report(); ?????} ?????//看完還是要簽名的 ?????public?void?sign(String?name){ ?????????????this.sr.sign(name); ?????} } 看到沒,裝飾類還是把動作的執行委托給需要裝飾的對象,Decorator抽象類的目的很簡單,就是要讓子類來封裝SchoolReport的子類,怎么封裝?重寫report方法!先看HighScoreDecorator實現類,如代碼清單17-7所示。 代碼清單17-7 最高成績修飾 public?class?HighScoreDecorator?extends?Decorator?{ ?????//構造函數 ?????public?HighScoreDecorator(SchoolReport?sr){ ?????????????super(sr); ?????} ?????//我要匯報最高成績 ?????private?void?reportHighScore(){ ?????????????System.out.println("這次考試語文最高是75,數學是78,自然是80"); ?????} ?????//我要在老爸看成績單前告訴他最高成績,否則等他一看,就掄起掃帚揍我,我哪里還有機會說啊 ?????@Override ?????public?void?report(){ ?????????????this.reportHighScore(); ?????????????super.report(); ?????} } 重寫了report方法,先調用具體裝飾類的裝飾方法reportHighScore,然后再調用具體構件的方法,我們再來看怎么匯報學校排序情況SortDecorator代碼,如代碼清單17-8所示。 代碼清單17-8 排名情況修飾 public?class?SortDecorator?extends?Decorator?{ ?????//構造函數 ?????public?SortDecorator(SchoolReport?sr){ ?????????????super(sr); ?????} ?????//告訴老爸學校的排名情況 ?????private?void?reportSort(){ ?????????????System.out.println("我是排名第38名..."); ?????}?? ?????//老爸看完成績單后再告訴他,加強作用 ?????@Override ?????public?void?report(){ ?????????????super.report(); ?????????????this.reportSort(); ?????} } 我準備好了這兩個強力的修飾工具,然后就“毫不畏懼”地把成績單交給老爸,看看老爸怎么看成績單的,如代碼清單17-9所示。 代碼清單17-9 老爸查看修飾后的成績單 public?class?Father?{ ?????public?static?void?main(String[]?args)?{ ?????????????//把成績單拿過來 ?????????????SchoolReport?sr; ?????????????//原裝的成績單 ?????????????sr?=?new?FouthGradeSchoolReport(); ?????????????//加了最高分說明的成績單 ?????????????sr?=?new?HighScoreDecorator(sr); ?????????????//又加了成績排名的說明 ?????????????sr?=?new?SortDecorator(sr); ?????????????//看成績單 ?????????????sr.report(); ?????????????//然后老爸一看,很開心,就簽名了 ?????????????sr.sign("老三");??//我叫小三,老爸當然叫老三 ?????} } 老爸一看成績單,聽我這么一說,非常開心,兒子有進步呀,從40多名進步到30多名,進步很大,躲過了一頓海扁。想想看,如果我還要增加其他的修飾條件,是不是就非常容易了,只要實現Decorator類就可以了!這就是裝飾模式。
                  <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>

                              哎呀哎呀视频在线观看