為什麼組合好於繼承?

2021-08-03 06:49:20 字數 1164 閱讀 6914

有過類似經驗的人可能不會奇怪,他一無所獲,無法發現這些類是幹什麼的,這個類只包含少數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:組合的本質

為什麼多用組合,少用繼承?

繼承和組合都是實現類重用的手段,何時用繼承何時用組合?繼承表示 is a 的關係,繼承是對已有的類做一番改造,以此獲得乙個特殊的版本。即將乙個較為抽象的類改造成能適用於某些特定需求的類。組合表示 has a 的關係,如果兩個類之間有明顯的整體 部分的關係,適合用組合,比如people和arm類。將a...

為什麼優先使用組合而不是繼承

繼承具有如下優點 實現新的類非常容易,因為基類的大部分功能都可以通過繼承關係自動賦予派生類 修改或者擴充套件繼承來的實現非常容易 只要修改父類,派生的類的行為就同時被修改了。初學物件導向程式設計的人會認為繼承真是乙個好東西,是實現復用的最好手段。但是隨著應用的深入就會發現繼承有很多缺點 繼承破壞封裝...

為什麼要優先使用組合 而不是繼承?

繼承具有如下優點 實現新的類非常容易,因為基類的大部分功能都可以通過繼承關係自動賦予派生類 修改或者擴充套件繼承來的實現非常容易 只要修改父類,派生的類的行為就同時被修改了。初學物件導向程式設計的人會認為繼承真是乙個好東西,是實 現復用的最好手段。但是隨著應用的深入就會發現繼承有很多缺點 繼承破壞封...