Re: [設計] 多用合成,少用繼承

作者: internaltide (internaltide)   2014-03-16 13:14:29
※ 引述《adrianshum (Alien)》之銘言:
: ※ 引述《internaltide (internaltide)》之銘言:
: : ~
: : EX.
: : // 物件A
: : class objectA{
: [43]
: : public objectC; //合成的物件C
: : public objectD;
: : public function func1(){...}
: : public function func2(){...}
: : }
: : // 繼承物件A的物件B
: : class objectB extend objectA{
: [43]
: : }
: : 可能同樣的物件內容B跟C,但實際上當要取得物件A的資料時
: : 物件B可以很直覺的直接使用物件A的屬性或間接使用方法來取得資料。
: : 但物件C就很麻煩了,變成我可能必須在A Class的建構式中時就要把資料
: : 想辦法塞到C物件,搞到後來變成當D物件也需要相同資料時,我又得重複
: : 塞相同的資料到物件D。 暈!!
: : 後來,我都是直接在物件A設了一個名為shareResources的陣列並宣告為Static,
: : 再把所有共用資源都往那個陣列塞。
: : 然後,無論合成物件或繼承物件都可以直接取用物件A的資料了。
: : 不曉得做法好不好,有沒有大師提供更聰明的方法??
: 首先,當static 牽連到繼承之類的話題,99% 都不會是正確的做法。
: 單想想,當你有兩個 A instance, 你所謂 shared resource 放的是
: 哪個 A 的東西。
static牽連到繼承有99%是錯的做法? 不太懂...
屬性被宣告為static時,不是就所有的A的實例所共用的了嗎?
: 然後看來你的認知有一個大問題。當談及 繼承 vs 合成,說的完全
: 不是你的在說的情況。在說以合成取代繼承是類似長這樣的東西:
: class A {...}
: class B extends A {.....} // 繼承
: class C { // 合成
: private A a;
: ....
: }
可能是因為強調合成物件要取資料的問題,所以例子focus的點有點偏掉了。
不過我的觀念:
當一個物件跟另一個物件具有Has-a的關係時就是一種合成關係,
某物件需要寄信功能時,不繼承mailClass而是設定它有一個屬性mailer,
然後讓mailer是mailClass的實例 =>這就叫合成取代繼承
這樣應該沒錯了吧 ^^
: 當然這種情況之下, A 通常會有某種interface, 而 C
: 也會提供這種 interface 並利用內部的 A instance 來
: 達成。
: 可是你在說的是
: class A {
: private C c;
: }
: 這完全是不相干的話題。
: 至於你的情況下 C 怎樣用到 A 的東西,這涉及你設計的問題,
: 很難一概而論。當然最常做的是 C 也存著 A 的 reference 然後
: C 經此 ref access 包含著自己的那個 A。但更常見的做法是做
: 好設計,讓 C 能不需要知道自己是被 A 所包含而單純做好自己的
: 工作就夠。
: Alien
嗯!! 讓 C 能不需要知道自己是被 A 所包含而單純做好自己的工作
物件導向設計是一條很遙遠的路啊!!
謝謝 Alien囉!!

Links booklink

Contact Us: admin [ a t ] ucptt.com