您的位置:首页 > 其它

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

2012-02-24 10:38 423 查看
问题分析:假如我们需要开发一个同时支持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#面向对象设计模式纵横谈系列讲座视频时,跟着李建忠老师一步一步的编写的,在此奉献出来,仅供大家参考
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: