面向对象设计模式之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图解:

     

    示例代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    /***
     * 没有使用桥接模式之前的设计实现代码
     * ***/
    namespace Bridge
    {
    
        public abstract  class Tank
        {
            public abstract void Run();
            public abstract void Shot();
            public abstract void Stop();
        }
    
        public class T50 : Tank
        {
    
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class PCT50 : T50
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class MobileT50 : T50
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class TVT50 : T50
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
    
    
    
        public class T75 : Tank
        {
    
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class PCT75 : T75
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class MobileT75 : T75
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class TVT75 : T75
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
    
        public class T90 : Tank
        {
    
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class PCT90 : T90
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class MobileT90 : T90
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
        public class TVT90 : T90
        {
            public override void Run()
            {
                //....
            }
    
            public override void Shot()
            {
                //....
            }
    
            public override void Stop()
            {
                //....
            }
        }
    
        /***
         * 实现的缺点:子类繁衍多,不能应对变化
         * ***/
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    /***
     * 使用Bridge模式后的代码实现
     * ***/
    namespace Bridge
    {
        /// <summary>
        /// 将不同平台坦克实现抽象出来(应对平台变化)
        /// </summary>
        public abstract class TankPlatformImplementation
        {
            public abstract void MoveTo();
            public abstract void Draw();
            public abstract void Stop();
        }
    
        /// <summary>
        /// PC平台的Tank
        /// </summary>
        public class PCTankImplementation:TankPlatformImplementation
        {
    
             public override void  MoveTo()
             {
     	       //PC上的实现代码
             }
    
             public override void  Draw()
             {
     	      //PC上的实现代码
             }
    
             public override void  Stop()
             {
     	       //PC上的实现代码
             }
        }
    
        /// <summary>
        /// Mobile平台的Tank
        /// </summary>
        public class MobileTankImplementation:TankPlatformImplementation
        {
    
             public override void  MoveTo()
             {
     	      // Mobile上的实现代码
             }
    
             public override void  Draw()
             {
     	      // Mobile上的实现代码
             }
    
             public override void  Stop()
             {
     	       // Mobile上的实现代码
             }
        }
    
        /// <summary>
        /// 坦克抽象类(应对坦克型号的变化)
        /// </summary>
        public abstract class Tank
        {
            TankPlatformImplementation tanklmp;//对象组合
            public Tank( TankPlatformImplementation tanklmp)
            {
                this.tanklmp = tanklmp;
            }
            public abstract void Run();
            public abstract void Shot();
            public abstract void Stop();
        }
    
        public class T50 : Tank
        {
            public T50(TankPlatformImplementation tanklmp)
                : base(tanklmp)
            { 
               
            }
    
            public override void Run()
            {
                //....
                //using tanklmp do something...
                //...
            }
    
            public override void Shot()
            {
                //....
                //using tanklmp do something...
                //...
            }
    
            public override void Stop()
            {
                //....
                //using tanklmp do something...
                //...
            }
        }
    
        public class T75 : Tank
        {
            public T75(TankPlatformImplementation tanklmp)
                : base(tanklmp)
            {
    
            }
    
            public override void Run()
            {
                //....
                //using tanklmp do something...
                //...
            }
    
            public override void Shot()
            {
                //....
                //using tanklmp do something...
                //...
            }
    
            public override void Stop()
            {
                //....
                //using tanklmp do something...
                //...
            }
        }
    
        public class App
        {
            public static void Main()
            {
               //手机平台游戏
                TankPlatformImplementation mobileTank=new MobileTankImplementation();
                Tank tank=new T50(mobileTank);
                //tank.Shot();
            }
        }
    }

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

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值