天天看點

為什麼組合好于繼承?

本文使用親身案例形象說明了軟體設計領域為什麼組合Composition要好于繼承(包括接口繼承),隻有需求分析域的問題分解,才有設計程式設計的組合應用。

來自遊戲公司GameSys的Yan Cui發表了博文:

This is why you need Composition over Inheritance

他試圖對一個剛剛接觸自己還是不太熟悉的系統進行一些舊代碼修改,很自然地,第一步首先是了解這些舊代碼是做什麼的,開始從需要改變的地方檢視類代碼了。

為什麼組合好于繼承?

有過類似經驗的人可能不會奇怪,他一無所獲,無法發現這些類是幹什麼的,這個類隻包含少數override方法,但是無法知道它們是如何搭配在一起工作的。

于是他進一步深入抽象類的多個層次,直到到達這個類層次的基類,從這個基類開始在順着繼承樹形結構來回好幾次,終于得到了一個有關業務邏輯分散在各層次之間的模糊概念。

為什麼組合好于繼承?

更有甚者,因為與原來樹形控制流有點差別,是以他們有得重新做一個新的樹形繼承結構的控制流,這些使人更加難以了解了。

這些都不是程式員想要,他們需要容易友善地且有信心地思考reason自己的代碼。或者說,讓自己的代碼像文章一樣有條理性。

是不是大部分人都有這樣類似痛苦經曆呢?那麼如何應用組合而不是繼承呢Composition over Inheritance?

Wiki中Composition over Inheritance定義是領域模組化:

使用組合而不是繼承是一種設計原則,能夠帶來設計的更高靈活性,帶給業務領域的類代碼更長時間的穩定性。

于Wiki這段結論,作者他說自己不是一個“下結論的粉絲”(a fan of conclusions

banq注:應試教育容易導緻人們喜歡下結論以及看文章時隻有看到下結論才認為自己看明白,因為考試題總是有唯一标準肯定終結的答案的,長期做考題容易被

誤導成這種思維模式)。

既然我們不直接接受這種結論,那麼我們就需要質疑反思,這段話到底是什麼意思呢?為什麼有這段話呢?能給出高靈活性和業務領域更穩定的證明或經驗證據嗎?

從作者的角度看,使用組合而不是繼承是鼓勵更好的問題域的解耦,起初如果你不将一個大問題分解成一個個更小的容易解決的小部分問題,後來你就無法使用組合來組裝它們。

Scott Wlaschin的railway oriented programming意味使用了一個很好的案例來說明在實踐中如何使用組合。

EventSourcing/CQRS的倡導者Greg Young還指出,問題域的分解是我們目前軟體工業的最大問題。

問題域的分解不隻是局限于代碼組織,微服務也是一個這方面的典型案例,從巨石monolithic鐵闆一塊哦系統遷移到微服務是另外一種問題域的解耦。

是以,我們需要使用利刀分解前面描述的類層次樹形結構,使用更小的、可組合的替換它們,包括使用具有這樣特點的語言如F#等。

參考:

Go語言是徹底的面向組合的并發語言

分解群組合的抽象方法

範疇category:組合的本質

繼續閱讀