作者
看,未来
责编
夕颜
出品
CSDN博客
桥接模式,号称设计模式中最抽象的一个,不是吹出来的啊。且看我能不能讲清楚啊。
这时候就体现出小故事的重要性了,这也是我为什么每篇设计模式都要先讲个小故事,便于理解记忆嘛。
手机配置的小故事
故事是别人的,网上一搜“桥接模式”,基本能看到这个故事。
手机品牌和软件是两个概念,不同的软件可以在不同的手机上,不同的手机可以有相同的软件,两者都具有很大的变动性。如果我们单独以手机品牌或手机软件为基类来进行继承扩展的话,无疑会使类的数目剧增并且耦合性很高。
原始构造
文字不明显,我们看图:
现在我们以手机品牌为抽象基类,每个品牌的手机底下都要求实现:我能打游戏、我能打电话、我能在线撩妹、我能听音乐等功能,于是形成上面这个图。
且不说M品牌手机和N品牌手机的功能重叠,就单说我现在要加一个功能,我能付钱,要加几个类?那我现在再加一个O品牌手机,要从哪儿入手,这个改动大不?
对上面这张类图的拓展,简直可以说是指数增长!!!
判处这个设计不及格,打回重构。
重构
前面已经暗示过了,每个品牌的手机,他们的功能都有互通点,比如都要能打电话、能上网、能拍照、能···不然基本卖不出去的。
那我们自然而然就可以联想到将这些功能抽象出来,在将这个抽象类聚合到品牌类下去,这样不就可以实现对功能与品牌的解耦嘛。
那,再看图:
现在呢,要添加一个品牌,就添加呗,没人拦着你,添加品牌和手机软件并没有一毛钱关系,要添加一个软件,那就添加嘛,畅通无阻的事儿。手机软件下还要加子类怎么办?看情况,如果对子类的拓展情况不理想,可以考虑再独立出来一个抽象类。
合成/聚合原则
合成/聚合原则:尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
合成/复用原则的好处:有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控的庞然大物。
桥接模式
抽象基类及接口:
Abstraction::Operation():定义要实现的操作接口AbstractionImplement::Operation():实现抽象类Abstaction所定义操作的接口,由其具体派生类ConcreteImplemenA、ConcreteImplemenA或者其他派生类实现。在Abstraction::Operation()中根据不同的指针多态调用AbstractionImplement::Operation()函数。
小故事代码实现
#includeiostreamusingnamespacestd;//手机软件类-抽象基类classsoftbase{public:virtualvoidrun()=0;};//手机软件-实现类classsoftmusic:publicsoftbase{public:voidrun(){coutMusic!endl;}};classsoftgame:publicsoftbase{public:voidrun(){coutwel