OOD沉思錄 之 繼承

一,繼承只應被用來爲特化層次結構建模
   實際上也就是要滿足LSP原則,水果類<-榴蓮的繼承是特化
二,派生類必須知道他們的基類,基類不應當知道他們的派生類
  複用的前提
三,基類中的所有數據都應該是私有的,不要使用保護數據(方法不在此原則約束下)
   數據封裝,物體的重量看起來可以用一個保護數據來表達,而不是get/set方法,但是考慮其他星球上,那麼重量的應該實現爲質量*加速度的時候呢?
四,理論上,繼承層次越深越好
   繼承越深,意味着複用的功能越多
五,如果沒有合適的可視化工具顯示類繼承層次,那麼在實踐中,繼承層次最合適的深度是7+-2(7是一個神奇的數字,是一個普通人能保持短期記憶的數字)
六,所有的抽象類都應該是基類
   沒有派生類的抽象類毫無意義,連創建都創建不了
七,與六對應,所有的基類都應該是抽象類
   違反這條原則的後果是將來可能會有大量的改名操作(在進一步抽象的過程中類名不在合適,在適應變化的時候會出現)
八,把數據,行爲和/或接口的共性儘可能地放到繼承層次的高端
    公共數據經常意味着公共行爲
九,如果兩個或多個類共享公共數據(但沒有公共行爲),那應該把公共數據放在一個類中,給個共享這些數據的類都包含這個類(而不是繼承)
   繼承所抽象的是行爲,而不是數據,和八對應.

   對靜態不變的類型/數據進行判斷的代碼基本上可以說是設計不到位的表現,如針對水果而言
   if(type is apple)...
   else if(type is orrange) ...
   ...
   但是對可變的數據進行判斷在一定程度上可以接受,但是如果邏輯複雜,則需要考慮狀態機/策略來封裝.
十,如果兩個或多個類有共同的數據和行爲(就是方法),那麼這些類的每一個都應當從一個表示了這些數據和方法的公共基類繼承
十一,如果兩個類或更多類共享公共接口,那麼只有他們需要被多態使用時,才需要公共基礎類.
   如果不需要多態使用,幹什麼要繼承而不是組合,組合優於繼承
十二,對對象類型的顯式的分情況分析一般都是錯誤的設計.在大多數這種情況下,設計者應當使用多態
   如:
   如果你是類型A,則做這件事
   如果你是類型B,則做那件事
   如果你是類型C,則做其他的一件事
十三,對屬性值的顯式分情況分析常常是錯誤的.類應該解耦合成一個繼承層次結構,每個屬性值都被變換成一個派生類
    紅綠黃球的例子
    如果顏色不影響到球的行爲,則不需要抽象一個球的基礎類,然後派生3個顏色球類
    反之,則需要
十四,不要通過繼承關係來爲類的動態語義建立模.試圖用靜態語義關係來爲動態語義建模會導致在運行時切換類型
    如門的狀態屬性:開和關,千萬不要出現OpenedDoor和ClosedDoor類,試圖用狀態機來處理.
十五,不要把類的對象變成派生類.對任何只有一個實例的派生類都要警惕.
  如下面的繼承關係就是問題:
  汽車製造商<=
              福特
              大衆
              本田
十六,如果你覺得需要在運行時創建新的類,那麼請退一步仔細想想是不是要創建對象.把這些對象概括成一個類
  組合模式是一個很明顯的例子
十七,在派生類中用空方法來覆蓋基類中的方法應該是非法的.
  如果這樣做可行的話,任何類都可以成爲任何其他類的派生類,反正把基類的所有方法都用空方法屏蔽掉然後加自己的方法就是.
十八,不要把可選包含(可能爲null的屬性)同對繼承的需要混淆起來.否則會帶來氾濫成災的類.
  狗<=會搖尾巴的狗,不會搖尾巴的狗,尾巴受傷的狗,等等
十九,在創建繼承層次時,試着創建可複用的框架,而不是可複用的類
  關注創建的是接口,而不是具體的類.與DIP原則類似

經典故事:
  按照第一想法,所有的哺乳動物都是懷胎產子,矛盾在鴨嘴獸是哺乳動物,但是是蛋生,那麼我們該怎麼建立模型呢?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章