标签:继承体系 注意 不同的 xxxxxx show rtu 缺点 手机 oid
1 桥接模式
将抽象化与实现分离,使二者可以独立的变化。
合成/聚合复用原则:面向对象设计的一个重要原则,尽量使用合成/聚合,不使用继承。
《大话设计模式》中的例子:手机品牌下面派生了华为和苹果等手机品牌, 华为又派生了华为的通信录,华为的游戏;苹果又派生了苹果的通信录和游戏。如果再加入新的品牌中兴,还要再派生中兴的通信录和游戏。而中兴和华为的游戏可能是一样的。在这个案例中,手机品牌在变化,软件也在变化,其实是两个维度都在变化。如果用继承的话,因为两个维度都变化,会很麻烦。解决方案:隔离两个维度变化之间的影响,手机品牌是接口,派生出各种手机品牌;手机软件作为接口,各种软件继承它。手机品牌的一个成员是手机软件,相当于聚合,这样二者可以互相独立变化。
上述方案中,表示和实现解耦,两者可以独立的变化,abstraction(手机品牌)中维护一个abstraction Impelemnt(软件)的指针,需要采用不同的实现方式的时候只需要传入不同的实例就可以了。
适用场景:手机的品牌是变化的(不断的有新品牌加入进来),手机的功能也变化(游戏,通信录,视频,...),如果不分离的话,在原来的继承体系上,每增加一个功能,或者每次增加一个品牌,都要加入好多类。比如我加入个小米手机,就需要加入各种小米的功能。 这种多个变化因素在多个对象之间共享,可以将这些变化的部分抽象出来再聚合进去。
优点: 依赖倒置; 将可以共享的部分,抽象出来,用聚合代替继承。减少代码重复。
缺点: 客户必须清楚的知道选择哪一种类型的实现。
注意:什么时候用继承,什么时候用聚合? 看变化是几维的,这里有2个维度,品牌和功能,如果只有一个维度,用继承就可以。
2 例子:
一个画板的形状可以是圆形的,正方形的,颜色可以是红色,绿色。
class Implementor { public: virtual void Show() {} }; class Implementor1 : public Implementor { public: virtual void Show() { XXXXXX; } }; class Implementor2 :public Implementor { public: virtual void show() { XXXXXX } }; class Abstractor { Implementor * _implementor; public: virtual void SetImplementor(Implementor* ot) { this->_iplementor = ot; } virtual void operatoe() { _implementor->Show(); } }; class RefindAbstractor: public Abstractor { }; int mian() { Implementor* im1 = new Implementor1(); Implementor2 * im2 = new Implementor2(); RefinedAbstractor *re = new ReefindeAbstractor(); re->SetImplementor(im1); re->operate(); re->SetIpeementor(im2); re->operate(); }
标签:继承体系 注意 不同的 xxxxxx show rtu 缺点 手机 oid
原文地址:http://www.cnblogs.com/liufei1983/p/7106684.html