老生常谈:桥接模式 男娘i 2022-04-01 13:19 148阅读 0赞 对于B/S架构来说,我一直想结合实际开发环境来学习设计模式,感觉这样印象会更加深,起码你知道在什么场合下应用它。之前也写过十多篇设计模式的文章,之所以没有写完,主要因为经验不够,感觉不到其它设计模式在B/S架构中的应用场合和威力,这篇我用桥接模式实现一个图书销售后计算最终售价的模块。 **假想案例说明:**出版社在出版的书后会在多家书店销售,**假如**所有的书的销售都由一个总公司负责销售,它可以控制书的销售方式,例如:计算机书打八折,生活类的打七折等。同时公司可以选择地区经销商做为二级代理,二级代理都必须服从公司的促销方式,如果公司打折,二级代理也要打折,否则二级代理不能私自打折。同时总公司会根据二级代理的销售业绩分为不同的二级代理,例如:钻石,黄金,VIP等,它们在得到的回扣上会有不同。 **需要的知识**:"开-闭"原则(OCP)以及组合/聚合复用原则(CARP)。至于组合模式可以参考这篇文章:[老生常谈:组合模式][Link 1] **结构图**:这里我用图书销售价格计算模块来具体说明,并不是标准图。 ![2009-1-23-bridge.jpg][] **桥接模式的定义**:【GOF95】桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。 1:抽象化:存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待【LISKOV94】。可以是接口也可以是抽象类,用来定义一系列的操作定义。 2:实现化:抽象化给出的具体实现,就是实现化。也是平常说的具体类,负责实现抽象类或者是接口定义的方法等。 3:脱耦:所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。可以看出,这个系统含有两个等级结构,也就是: 1):由抽象化角色和修正抽象化角色组成的抽象化等级结构。 在结构图上由抽象化角色book,修正抽象化角色lifebook和computerbook构成。 2):由实现化角色和两个具体实现化角色所组成的实现化等级结构。在结构图上由diamondProxy,goldProxy,VIPProxy构成。 **桥梁模式所涉及的角色**有:这里为了看的清楚些,我加上各部分的示例代码。 1:抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。 abstract public class book \{ abstract public double promotionPrice(); public proxy \_proxy; /// <summary> /// 图书名称 /// </summary> public string bookName \{ get ; set ; \} \} 2:修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。 public class computerBook:book \{ /// <summary> /// 计算机图书打八折 /// </summary> /// <param name="bookPrice"> 图书原价 </param> /// <returns> 经过图书正常打折以及代理商后的价格 </returns> public override double promotionPrice() \{ // throw new NotImplementedException(); bookPrice = bookPrice \* 0.8 ; bookPrice = base .\_proxy.proxyPrice(bookPrice); return bookPrice; \} /// <summary> /// 图书价格 /// </summary> double bookPrice; /// <summary> /// 构造函数 /// </summary> /// <param name="\_bookPrice"></param> public computerBook( double \_bookPrice) \{ this .bookPrice = \_bookPrice; base .bookName = " C\#入门经典 " ; \} \} 3:实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。 abstract public class proxy \{ abstract public double proxyPrice( double promotionPrice); /// <summary> /// 代理商名称 /// </summary> public string proxyName \{ get ; set ; \} /// <summary> /// 代理商级别 /// </summary> public string proxyTye \{ get ; set ; \} \} 4:具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。 public class diamondProxy:proxy \{ /// <summary> /// 钻石级代理商的价格为图书正常打完折后的价格的八折 /// </summary> /// <param name="promotionPrice"></param> /// <returns></returns> public override double proxyPrice( double promotionPrice) \{ return promotionPrice \* 0.8 ; \} // decimal promotionPrice; public diamondProxy() \{ base .proxyName = " 北京代理 " ; base .proxyTye = " 钻石代理 " ; \} \} **代码以及结构图分析**:可以看出在桥接模式中使用了组合模式,如果不用组合模式呢,当然也就不是桥接了,下面的结构图是用继承实现的方案,在结构图中有一个总的计算价格的接口IBook,下面是两种打折方案的子类接IPromotion,IProxy。 **使用继承的结构图如下:** ![2009-1-23-bridge-2.jpg][] **使用继承的代码如下:** interface IBook \{ /// <summary> /// 图书的价格接口 /// </summary> /// <returns></returns> double price(); \} interface IPromotion:IBook \{ /// <summary> /// 图书正常打折后的价格接口 /// </summary> /// <returns></returns> double promotionPrice(); \} interface IProxy:IBook \{ /// <summary> /// 代理商打折后的价格接口 /// </summary> /// <returns></returns> double proxyPrice(); \} public class computerBook:IPromotion \{ /// <summary> /// 计算机图书打八折后的价格 /// </summary> /// <returns></returns> public double promotionPrice() \{ return bookprice \* 0.8 ; \} double bookprice; public computerBook( double \_bookprice) \{ this .bookprice = \_bookprice; \} /// <summary> /// 返回打折后的图片价格 /// </summary> /// <returns></returns> public double price() \{ return this .promotionPrice(); \} \} public class diamondProxy:IProxy \{ /// <summary> /// 钻石代理商打八折后的价格 /// </summary> /// <returns></returns> public double proxyPrice() \{ return bookprice \* 0.8 ; \} double bookprice; public diamondProxy( double \_bookprice) \{ this .bookprice = \_bookprice; \} /// <summary> /// 返回打折后的图片价格 /// </summary> /// <returns></returns> public double price() \{ return this .proxyPrice(); \} \} **桥接与使用继承的比较:** 1:在接口数量上来看,桥接要少一个,继承用了三个; 2:从客户端调用程序来看:可以看出桥接模式要简洁的多。 1):使用桥接的客户端调用: // 图书类型:计算机,打折为八折 // 原始价格:100RMB // 代理商级别:钻石,打折为八折 // 计算最后实际等到的金额 book \_Book = new computerBook( 100.0 ); \_Book.\_proxy = new diamondProxy(); double proxyPrice = \_Book.promotionPrice(); 2):使用继承的客户端调用: // 实例化一本计算机图书 IBook \_Book = new computerBook( 100.0 ); // 得到计算机打完折后的价格 double price = \_Book.price(); // 实例化一位钻石代理商 IBook \_BookProxy = new diamondProxy(price); // 把正常打折后的图片价格做为基数来计算最终价格 price = \_BookProxy.price(); 3:从两者的业务逻辑代码来看,显然是桥接模式精简不少,起码在代码量上是这样。 **桥梁模式适用场合:**根据上面的分析,在以下的情况下应当使用桥梁模式: 1:如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。 2:设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。 3:一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。 **总结:**本文通过一个具体的书店销售图书中计算图书最终价格模块来说明桥接模式的应用,系统可以轻松的在图书打折方式和代理商之间扩展及维护。 **注:** 本文引用:《Java与模式》 [Link 1]: http://www.cnblogs.com/ASPNET2008/archive/2008/08/31/1279571.html [2009-1-23-bridge.jpg]: /images/20220401/1c3bc92ac3f7435880786c66b10dc8f9.png [2009-1-23-bridge-2.jpg]: /images/20220401/64f32dbaedd44b7083ba1be51b98f2f1.png
相关 桥接模式 一、前言 `为什么你的代码那么多ifelse` 同类的业务、同样的功能,怎么就你能写出来那么多`ifelse`。很多时候一些刚刚从校园进入企业的萌新,或者一部分从小公司 绝地灬酷狼/ 2022年10月16日 07:57/ 0 赞/ 31 阅读
相关 桥接模式 1.桥接模式概述 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合 谁践踏了优雅/ 2022年09月28日 05:48/ 0 赞/ 28 阅读
相关 桥接模式 定义 桥接模式:将抽象部分与它实现部分分离,使它们都可以独立地变化。 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将 电玩女神/ 2022年05月14日 10:28/ 0 赞/ 59 阅读
相关 桥接模式 我是在脑壳疼的情况下(今天的工作的量很大,内容很丰富,我很开心,以至于脑壳疼)写下这篇关于桥接模式的文章,不正之处请多指教。 何谓桥接模式,用一座桥连接起来的模式,珠港澳大桥 分手后的思念是犯贱/ 2022年05月08日 17:00/ 0 赞/ 149 阅读
相关 老生常谈:桥接模式 对于B/S架构来说,我一直想结合实际开发环境来学习设计模式,感觉这样印象会更加深,起码你知道在什么场合下应用它。之前也写过十多篇设计模式的文章,之所以没有写完,主要因为经验不够 男娘i/ 2022年04月01日 13:19/ 0 赞/ 149 阅读
相关 桥接模式 > 本文总结摘自刘伟老师的《设计模式》和程杰老师的《大话设计模式》 1.定义 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。(桥接模式用关联关系来降低 ╰半橙微兮°/ 2022年01月27日 09:37/ 0 赞/ 261 阅读
相关 桥接模式 前言 1、合成/聚合复用原则,尽量使用使用合成/聚合,尽量不要使用类继承。 2、合成和聚合都是关联的特殊种类。 聚合表示弱的 ‘拥有’ 关系,体现的是A 红太狼/ 2021年12月09日 00:51/ 0 赞/ 80 阅读
相关 桥接模式 桥接模式:是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。 这种模式涉及到一个作 我会带着你远行/ 2021年09月17日 03:34/ 0 赞/ 388 阅读
相关 桥接模式 10.桥接模式 ![70][] class Client { static void Main(string[] arg ╰+攻爆jí腚メ/ 2021年09月16日 23:56/ 0 赞/ 358 阅读
相关 桥接模式 一 概述 现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系: ![在这里插入图片描述][watermark £神魔★判官ぃ/ 2021年07月24日 20:06/ 0 赞/ 518 阅读
还没有评论,来说两句吧...