Re: [设计] 多用合成,少用继承

楼主: qrtt1 (有些事,有时候。。。)   2014-03-16 16:11:57
※ 引述《internaltide (internaltide)》之铭言:
: 看了一些设计模式跟物件导向的书,都会提到一个观念就是
: 多用合成,少用继承
: 之后,自己在写程式时有尝试着多使用合成去取代继承
: 但是发现被合成物件(物件C、D)要取得合成物件(物件A)的资料时都会很不方便
: EX.
: // 物件A
: class objectA{
: public static shareResources;
: public attr1;
: public attr2;
: public objectC; //合成的物件C
: public objectD;
: public function func1(){...}
: public function func2(){...}
: }
: // 继承物件A的物件B
: class objectB extend objectA{
: ~~~~~~~~~~~~
: ~~~~~~~~~~~~
: }
: 可能同样的物件内容B跟C,但实际上当要取得物件A的资料时
: 物件B可以很直觉的直接使用物件A的属性或间接使用方法来取得资料。
: 但物件C就很麻烦了,变成我可能必须在A Class的建构式中时就要把资料
: 想办法塞到C物件,搞到后来变成当D物件也需要相同资料时,我又得重复
: 塞相同的资料到物件D。 晕!!
看起来 class A 只是被当成存放资料的“结构”而不是当作承担某些责任的行为者。
继承 class A 若只是需要有一样的结构,就只是单纯在语法上用了继承。
这是你的实作选择。
设计上不管你要继承还是合成,
重点是使用这组“类别”、“函式库”的使用者觉得好用。
什么情况是好用?要加新功能或扩充旧有物件很方便,能容易地面对需求改变
(但得需符合你设计时的考量,对未知的变化是难以掌握的)
真的站到设计模式的视野后,就不会再讨论在写法上是继承还是合成。
在实作结构上,该用什么就会用什么,不会刻意去避免不用哪一种写法。
以“装饰者”来说,总得继承要被装饰的物件
(这是 java 这类静态语言的观点,不同语言特性就可能不同了^^)
他装饰了之后,专注在改变原始物件的“外显”行为。
对于他装饰的物件,极少需要用它“内部”的资料。
所以,即使原来的资料有千百个 field 也不关他的事。
client side 只需要呼叫同样的 method 即有不同的效果。
以我个人的想法,目前你被资料字段细节的操作迷惑了。
目前你的变化是,有“新需求”就得同时加新的“类别”
并改变“原始设计”里的 shareResources。
这明显是个不优的设计,为什么呢?
因为提供原始设计的人,跟后来使用的人不一定是同一个人。
也可能不是同一个公司,也可能没有 source code。
于是加新东西要改原始的设计是极不合理的情况。
我前面提的装饰者模式就是一种不会动到原始设计的情境。
多数的设计模式书籍也都在绕着这些核心打转
本质上它们就是“开放封闭原则”目前你的设计就不合乎这原则。
而随着新功能的扩充,不断变大的 class A,
就会渐渐失去原先设计它的本意,打破“单一责任原则”只是时间的问题
(或早就不符合了)
: 后来,我都是直接在物件A设了一个名为shareResources的阵列并宣告为Static,
: 再把所有共用资源都往那个阵列塞。
: 然后,无论合成物件或继承物件都可以直接取用物件A的资料了。
: 不晓得做法好不好,有没有大师提供更聪明的方法??
“感觉”起来是不必要的修改。
如果先出道的 A 获得了一个新的资源 x 在 shareResources 内,
A 知道该怎么用它吗?显然 A 不会知道,但 A 可能在设计时对 shareResources
有某些预想,例如 A 有权可以 reset shareResources 内的所有的东,
若 A 的子孙触发了这个 reset 的动作,再来使用 x 就会产生非预期的效果。
为了避免这种非预期的情况,细心得设计者每次修改时,就得检简 A
以及“所有”继承 A,且可能触发 reset 动件的类别,是否有机会存在特定的
call sequence 后,产生 side effect。
对于刚接手 code 的人,就没 sense 要“检查”那么多部分才不会弄坏“设计”
那就可能一边开发,一边替 bug 产生的“加速度”增加。
听起来就冷汗直流,on borad 后看到这样的情况,
会想“还是趁大家还不熟,换下一家呗”
那新增的 x 只是一个说例,它可以推扩成 y, z, ...。
说到道,当你在最原始的设计变更加入 x 后,那它就是整棵继承树共通的责任了。
大家都有责任维护皇城内(shareResources)的和平。
设法把责任(x)分散到独立的物件,大家的“共业”少一点,皇城的分争才会少一些。
不用常常莫名奇妙出 bug,再想办法推动和谐社会。
Design Pattern 看人参,如此警世呐~~

Links booklink

Contact Us: admin [ a t ] ucptt.com