免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      快速云:需求決定設(shè)計(jì) 面向?qū)ο笞畲蟮脑O(shè)計(jì)陷阱

      快速云:需求決定設(shè)計(jì) 面向?qū)ο笞畲蟮脑O(shè)計(jì)陷阱

      通過面向?qū)ο蟮乃悸?,我們可以把任何事物都看成一個(gè)對象然后單獨(dú)處理,從理想的角度,任何一個(gè)微小的單元都可以以一個(gè)對象的形式表示。比如我們可以用如下代碼表示一個(gè)人以及它的姓名

        1.不分離姓名

      class 人 {

      public string 姓名;

      }  但是這個(gè)世界是很復(fù)雜的,姓名本身是由姓和名組成的。如果我們需要需要單獨(dú)處理姓和名時(shí),要怎么辦?于是我們可以這么拆分:

        2.直接分離姓名

      class 人 {

      public string 姓; public string 名;

      }  但我們會(huì)碰到這個(gè)問題:姓和名本身是一個(gè)整體,處理姓名的邏輯不應(yīng)該放在人這個(gè)類里面,而應(yīng)該單獨(dú)提取出來。于是代碼改為:

        3. 提取姓名為單獨(dú)一個(gè)類,然后單獨(dú)處理

      class 人 {

      public 姓名 姓名;

      }

      class 姓名 { public string 姓; public string 名;

      }  這是一個(gè)非常理想的狀態(tài):任何事物都被表示成了一個(gè)獨(dú)立的對象。但其實(shí)作者都是懶的,沒人會(huì)愿意為姓名單獨(dú)寫一個(gè)類然后單獨(dú)處理它。除非邏輯非常復(fù)雜需要單獨(dú)處理時(shí),才會(huì)選擇把它提取出來。

        同樣一個(gè)人,把它寫成面向?qū)ο蟮拇a之后,卻有3種不同的寫法(1. 不分離姓名。 2. 直接分離姓名。 3.提取姓名為單獨(dú)一個(gè)類,然后單獨(dú)處理)。而決定我們用哪個(gè)寫法的是最需求。需求是軟件開發(fā)中最不穩(wěn)定的因素,因此面向?qū)ο蟮拇a經(jīng)常需要重構(gòu)和重寫。這就是面向?qū)ο笾械囊粋€(gè)設(shè)計(jì)陷阱

        再來看一個(gè)例子:

      abstract class 魚 {private int 價(jià)格; private int 口感;public int get價(jià)格(){ return 價(jià)格; } public int get口感(){ return 口感; } public abstract string get名字();}

      class 鯉魚: 魚 { public override string get名字() { return “鯉魚”; }}

      class 桂魚: 魚 {  public override string get名字() { return “桂魚”;  }}  這是一個(gè)最普通的面向?qū)ο蟮拇a了。從上面看似乎完美到?jīng)]有任何問題:通過魚這個(gè)類以及它的多態(tài)特性,我們可以很輕松地處理所有魚。

        但是這時(shí)加了一個(gè)需求,我們需要處理金魚,于是寫了這么一行代碼:

      class 金魚: 魚 {  public override string get名字() { return “金魚”;  }}  看上去依然完美,但問題是:金魚是不能吃的,獲取它的口感是沒有任何意義的!但是通過繼承,我們的金魚也是可以有口感的。同時(shí),還浪費(fèi)了一個(gè)內(nèi)存用來存儲(chǔ)這個(gè)沒有意義的口感字段。

        現(xiàn)實(shí)中,很多人都忽視了這個(gè)問題:反正沒意義,這個(gè)函數(shù)不要調(diào)用就行了。對的,但如果一個(gè)繼承了一個(gè)父類之后,5個(gè)函數(shù)是有意義的,20個(gè)函數(shù)是沒有意義的,這時(shí)我想作者該犯潔癖了吧。問題主要是在于繼承一個(gè)類之后,有一些成員是不必要或者無意的,有2個(gè)改法:

        1. 讓金魚不繼承于魚:這不科學(xué),金魚本來就是魚,除了口感,其它的繼承都是有意義并且需要使用的。

        2. 提取一個(gè)公共父類:

      abstract class 魚 { private int 價(jià)格; public int get價(jià)格(){ return 價(jià)格; } public virtual int get口感() { throw new Exception(“無意義”) } public abstract string get名字();}

      abstract class 可以吃的魚 : 魚 { private int 口感; public override int get口感() { return 口感; }}

      class 鯉魚: 可以吃的魚 { public override string get名字() { return “鯉魚”; }}

      class 桂魚: 可以吃的魚 {  public override string get名字() { return “桂魚”;  }}

      class 金魚: 魚 {  public override string get名字() { return “金魚”;  }}  仔細(xì)研究,你會(huì)發(fā)現(xiàn)網(wǎng)上很多代碼,它定義了一個(gè)抽象類,并且名字是 XXXBase, XXXCore 或者一個(gè)類XXX還定義了一個(gè)類叫 XXXImpl 。這些抽象類就像上例中可以吃的魚這個(gè)類一樣,都是為了繼承而存在的。這里,我們同樣有這個(gè)問題:

        父類的設(shè)計(jì)會(huì)因?yàn)樾枨蠛妥宇惖脑黾雍筒坏貌蛔饕恍┬薷?如提取另外一個(gè)公共父類)。因此面向?qū)ο蟮拇a經(jīng)常需要重構(gòu)和重寫。這就是面向?qū)ο笾械挠忠粋€(gè)設(shè)計(jì)陷阱。

        總結(jié)一下上面的2個(gè)例子,就是:需求增加,代碼就要重構(gòu)。所以很多人認(rèn)為這是一個(gè)只能靠經(jīng)驗(yàn)才能解決的問題,只要寫的代碼夠多了,就能預(yù)感到未來的需求并減少重構(gòu)量。就像上例中,我們有經(jīng)驗(yàn)就會(huì)先寫好一個(gè)可以吃的魚這個(gè)類。但這終究是一個(gè)幻想,沒有誰能真正預(yù)知到未來的需求。很多作者都喜歡預(yù)留一個(gè)XXX接口,然后寫了一個(gè)XXXImpl的實(shí)現(xiàn)類,認(rèn)為以后只寫另外一個(gè)XXXImpl2類,就可以重用處理XXX接口時(shí)的所有代碼。其實(shí)以后需要寫另外一個(gè)XXXImpl2類的概率幾乎為0 。這樣反而讓修改XXX接口的成本上升不少。

        需求決定設(shè)計(jì),需求變化會(huì)導(dǎo)致不斷重新設(shè)計(jì)。這就是面向?qū)ο蟮淖畲笤O(shè)計(jì)陷阱。

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年6月27日 15:06
      下一篇 2022年6月27日 15:07

      相關(guān)推薦

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息