• 面向对象设计模式之Bridge桥接模式(结构型)


    问题分析:假如我们需要开发一个同时支持PC和手机的坦克游戏,游戏在PC和手机上功能都一样,都有同样的类型,面临同样的功能需求变化,比如坦克可能有多种不同的型号:T50,T75,T90..对于其中的坦克设计,我们可能很容易设计出来一个Tank的抽象类,然后各种不同型号的Tank继承自该类,但是PC和手机上的图形绘制、声效、操作等实现完全不同...因此对于各种型号的坦克,都 要提供各种不同平台上的坦克实现;而这样的设计带来了很多问题:有很多重复代码,类的结构过于复杂,难以维护,最致命的是引入任何新的平台,比如TV上的Tank游戏,都会让整个类层次级结构复杂化

    动机:思考上述问题的症结,事实上由于Tank类型的固有逻辑,使得Tank类型具有了两个变化的维度——一个变化的维度为“平台的变化”,一个变化的维度为“型号的变化”;如何应对这种“多维度的变化”?如何利用面向对象技术使得Tank类型可以轻松地沿着“平台”和“型号”两个方向变化,而不引入额外的复杂度
    意图:将抽象部分和实现部分分离(将一个事物中多个维度的变化分离),使它们可以独立的变化 即将不同纬度的变化抽象出来,并子类化它们,用对象组合的方式实现应对其变化

    可适用性:

    • 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
    • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时B r i d g e 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
    • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
    • (C + +)你想对客户完全隐藏抽象的实现部分。在C + +中,类的表示在类接口中是可见的。
    • 有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。R u m b a u g h 称这种类层次结构为“嵌套的普化”(nested generalizations )。
    • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是C o p l i e n 的S t r i n g 类[ C o p 9 2 ],在这个类中多个对象可以共享同一个字符串表示(S t r i n g R e p )。

      UML图解:

      示例代码:

        1 using System;
        2 using System.Collections.Generic;
        3 using System.Linq;
        4 using System.Text;
        5 
        6 /***
        7  * 没有使用桥接模式之前的设计实现代码
        8  * ***/
        9 namespace Bridge
       10 {
       11 
       12     public abstract  class Tank
       13     {
       14         public abstract void Run();
       15         public abstract void Shot();
       16         public abstract void Stop();
       17     }
       18 
       19     public class T50 : Tank
       20     {
       21 
       22         public override void Run()
       23         {
       24             //....
       25         }
       26 
       27         public override void Shot()
       28         {
       29             //....
       30         }
       31 
       32         public override void Stop()
       33         {
       34             //....
       35         }
       36     }
       37     public class PCT50 : T50
       38     {
       39         public override void Run()
       40         {
       41             //....
       42         }
       43 
       44         public override void Shot()
       45         {
       46             //....
       47         }
       48 
       49         public override void Stop()
       50         {
       51             //....
       52         }
       53     }
       54     public class MobileT50 : T50
       55     {
       56         public override void Run()
       57         {
       58             //....
       59         }
       60 
       61         public override void Shot()
       62         {
       63             //....
       64         }
       65 
       66         public override void Stop()
       67         {
       68             //....
       69         }
       70     }
       71     public class TVT50 : T50
       72     {
       73         public override void Run()
       74         {
       75             //....
       76         }
       77 
       78         public override void Shot()
       79         {
       80             //....
       81         }
       82 
       83         public override void Stop()
       84         {
       85             //....
       86         }
       87     }
       88 
       89 
       90 
       91     public class T75 : Tank
       92     {
       93 
       94         public override void Run()
       95         {
       96             //....
       97         }
       98 
       99         public override void Shot()
      100         {
      101             //....
      102         }
      103 
      104         public override void Stop()
      105         {
      106             //....
      107         }
      108     }
      109     public class PCT75 : T75
      110     {
      111         public override void Run()
      112         {
      113             //....
      114         }
      115 
      116         public override void Shot()
      117         {
      118             //....
      119         }
      120 
      121         public override void Stop()
      122         {
      123             //....
      124         }
      125     }
      126     public class MobileT75 : T75
      127     {
      128         public override void Run()
      129         {
      130             //....
      131         }
      132 
      133         public override void Shot()
      134         {
      135             //....
      136         }
      137 
      138         public override void Stop()
      139         {
      140             //....
      141         }
      142     }
      143     public class TVT75 : T75
      144     {
      145         public override void Run()
      146         {
      147             //....
      148         }
      149 
      150         public override void Shot()
      151         {
      152             //....
      153         }
      154 
      155         public override void Stop()
      156         {
      157             //....
      158         }
      159     }
      160 
      161     public class T90 : Tank
      162     {
      163 
      164         public override void Run()
      165         {
      166             //....
      167         }
      168 
      169         public override void Shot()
      170         {
      171             //....
      172         }
      173 
      174         public override void Stop()
      175         {
      176             //....
      177         }
      178     }
      179     public class PCT90 : T90
      180     {
      181         public override void Run()
      182         {
      183             //....
      184         }
      185 
      186         public override void Shot()
      187         {
      188             //....
      189         }
      190 
      191         public override void Stop()
      192         {
      193             //....
      194         }
      195     }
      196     public class MobileT90 : T90
      197     {
      198         public override void Run()
      199         {
      200             //....
      201         }
      202 
      203         public override void Shot()
      204         {
      205             //....
      206         }
      207 
      208         public override void Stop()
      209         {
      210             //....
      211         }
      212     }
      213     public class TVT90 : T90
      214     {
      215         public override void Run()
      216         {
      217             //....
      218         }
      219 
      220         public override void Shot()
      221         {
      222             //....
      223         }
      224 
      225         public override void Stop()
      226         {
      227             //....
      228         }
      229     }
      230 
      231     /***
      232      * 实现的缺点:子类繁衍多,不能应对变化
      233      * ***/
      234 }using System;
      235 using System.Collections.Generic;
      236 using System.Linq;
      237 using System.Text;
      238 
      239 /***
      240  * 使用Bridge模式后的代码实现
      241  * ***/
      242 namespace Bridge
      243 {
      244     /// <summary>
      245     /// 将不同平台坦克实现抽象出来(应对平台变化)
      246     /// </summary>
      247     public abstract class TankPlatformImplementation
      248     {
      249         public abstract void MoveTo();
      250         public abstract void Draw();
      251         public abstract void Stop();
      252     }
      253 
      254     /// <summary>
      255     /// PC平台的Tank
      256     /// </summary>
      257     public class PCTankImplementation:TankPlatformImplementation
      258     {
      259 
      260          public override void  MoveTo()
      261          {
      262             //PC上的实现代码
      263          }
      264 
      265          public override void  Draw()
      266          {
      267            //PC上的实现代码
      268          }
      269 
      270          public override void  Stop()
      271          {
      272             //PC上的实现代码
      273          }
      274     }
      275 
      276     /// <summary>
      277     /// Mobile平台的Tank
      278     /// </summary>
      279     public class MobileTankImplementation:TankPlatformImplementation
      280     {
      281 
      282          public override void  MoveTo()
      283          {
      284            // Mobile上的实现代码
      285          }
      286 
      287          public override void  Draw()
      288          {
      289            // Mobile上的实现代码
      290          }
      291 
      292          public override void  Stop()
      293          {
      294             // Mobile上的实现代码
      295          }
      296     }
      297 
      298     /// <summary>
      299     /// 坦克抽象类(应对坦克型号的变化)
      300     /// </summary>
      301     public abstract class Tank
      302     {
      303         TankPlatformImplementation tanklmp;//对象组合
      304         public Tank( TankPlatformImplementation tanklmp)
      305         {
      306             this.tanklmp = tanklmp;
      307         }
      308         public abstract void Run();
      309         public abstract void Shot();
      310         public abstract void Stop();
      311     }
      312 
      313     public class T50 : Tank
      314     {
      315         public T50(TankPlatformImplementation tanklmp)
      316             : base(tanklmp)
      317         { 
      318            
      319         }
      320 
      321         public override void Run()
      322         {
      323             //....
      324             //using tanklmp do something...
      325             //...
      326         }
      327 
      328         public override void Shot()
      329         {
      330             //....
      331             //using tanklmp do something...
      332             //...
      333         }
      334 
      335         public override void Stop()
      336         {
      337             //....
      338             //using tanklmp do something...
      339             //...
      340         }
      341     }
      342 
      343     public class T75 : Tank
      344     {
      345         public T75(TankPlatformImplementation tanklmp)
      346             : base(tanklmp)
      347         {
      348 
      349         }
      350 
      351         public override void Run()
      352         {
      353             //....
      354             //using tanklmp do something...
      355             //...
      356         }
      357 
      358         public override void Shot()
      359         {
      360             //....
      361             //using tanklmp do something...
      362             //...
      363         }
      364 
      365         public override void Stop()
      366         {
      367             //....
      368             //using tanklmp do something...
      369             //...
      370         }
      371     }
      372 
      373     public class App
      374     {
      375         public static void Main()
      376         {
      377            //手机平台游戏
      378             TankPlatformImplementation mobileTank=new MobileTankImplementation();
      379             Tank tank=new T50(mobileTank);
      380             //tank.Shot();
      381         }
      382     }
      383 }

      注:本示例代码是本人学习Webcast C#面向对象设计模式纵横谈系列讲座视频时,跟着李建忠老师一步一步的编写的,在此奉献出来,仅供大家参考

    作者:JumpByte
    来源:http://www.cnblogs.com/yja9010
    更新: http://jumpbyte.cn
    声明:本博客原创文字只代表本人的观点或结论,于网站他人无关,非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    Windows API—CreateEvent—创建事件
    C++的注册和回调
    Python内置模块-logging
    使用 C++ 处理 JSON 数据交换格式
    Python生成器
    5.Spring-Boot缓存数据之Redis
    6.Spring-Boot项目发布到独立的tomcat中
    7.Spring-Boot自定义Banner
    8.Spring-Boot之SpringJdbcTemplate整合Freemarker
    9.Spring-Boot之Mybatis-LogBack-Freemarker
  • 原文地址:https://www.cnblogs.com/yja9010/p/3178773.html
Copyright © 2020-2023  润新知