您的位置:首页 > 移动开发 > Unity3D

设计模式深入学习---Bridge桥接模式(结构型模式)

2017-01-13 16:38 603 查看
       上期我们说了 Adapter适配器模式的用法,这次我们介绍下Bridge桥接模式。在介绍桥接模式的好处之前,我们先来看一个没有用该模式的一个小案例,然后再对比用了该模式的好处。
假设,我们制作一个手机游戏。该游戏只在安卓平台下面运行。

public class AndroidGame
{
public void Run()
{
Console.WriteLine("运行安卓手机游戏");
}
}
          现在我们老板说,为了加大市场份额,我们还要把这个游戏做到苹果平台去,然后我们在加一个苹果平台的游戏。这时我们利用之前学过的面向对象思想,应该得有一个平台的父类,让所有平台的游戏都基于这个父类,这样就可以统一运行方法了。

public class Platform
{
public virtual void Run()
{
}
}

public class AndroidGame:Platform
{
public override void Run()
{
Console.WriteLine("运行安卓手机游戏");
}
}

public class IOSGame : Platform
{
public override void Run()
{
Console.WriteLine("运行苹果手机游戏");
}
}
          到目前为止我们还没发现任何问题,就算我们在加入WindowsPhone平台,又或者是Web网页平台,我们的程序依然还可以保持高效,简洁。这时候,我们老板说了,我们游戏做的火了,赶紧再做一个社区功能,把玩家社交,娱乐结合起来。现在我们需要再制作一个社区功能,也就是平台下面有安卓,苹果。安卓和苹果下面分别有游戏,社区。好吧,那我们现在开始更改,重新设计架构代码。

public class Platform
{
public virtual void Run()
{
}
}
public class Android : Platform
{

}

public class IOS : Platform
{

}

//安卓游戏
public class AndroidGame : Android
{
public override void Run()
{
Console.WriteLine("运行安卓平台游戏");
}
}
//安卓社区
public class AndroidAPP : Android
{
public override void Run()
{
Console.WriteLine("运行安卓平台社区");
}
}

//苹果游戏
public class IOSGame : IOS
{
public override void Run()
{
Console.WriteLine("运行苹果平台游戏");
}
}
//苹果社区
public class IOSAPP : IOS
{
public override void Run()
{
Console.WriteLine("运行苹果平台社区");
}
}




   好了,费了不少时间,终于把需要增加的内容搞出来了,现在我们的社区也非常活跃,我们的玩家可以很好的使用我们的游戏和社区。这时候,问题其实已经出现, 如果老板接着说,我们要做音乐功能,打车功能,外卖功能,又或者下一款新游戏。基于我们的整个架构,就开始变得越来越麻烦。问题就在于我们使用面向对象的继承时带来的问题,比如对象的继承关系是在编译时候就定义好了,所以无法再运行时改变从父类继承的实现,子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换,这种依赖关系限制了灵活性并最终限制了复用性。
   OK,大半个篇幅说了上面的例子,其实是为了更好的展示我们的桥接模式的一个好处,其实桥接模式非常简单,它用的是合成/聚合复用原则。即优先使用对象合成/聚合,而不是类继承。我们现在多介绍下桥接模式的原理实现,什么叫合成/聚合呢? 聚合表示一种弱的"拥有"关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成这是一种强"拥有"关系,体现了严格的部分和整体关系,部分和整体的生命周期一样,比如说我们的电脑配件里面有硬盘,内存,CPU,GPU等等,里面的硬盘,内存,CPU,GPU部件是整体运行的,电脑和硬盘,内存,CPU,GPU是部分和整体的关系,他们统一运行,共同开关机,并且他们生命周期是一样的,于是电脑和CPU就是合成关系,而我们在机房里面可以看到里面有很多台电脑一块玩游戏,一块写程序,所以每台电脑都可以属于一个机房,一个机房可以有多台电脑,所以电脑和机房就是聚合关系。
   合成/聚合复用原则的好处是,优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上,这样类和类继承层次会保持较小规模,并且不太可能增长为一个庞然大物,就我们上面的例子,我们需要用的是对象的职责,而不是结构来考虑问题,所以我们重新梳理一下,我们的平台和各个平台是一个聚合关系,而游戏,社区,后面发展的各种听歌,打车,外卖功能和平台是合成关系,我们就可以把"平台"和"软件"抽象出来,让不同的平台和功能都分别继承与他们,这样要增加新的平台或者新的功能就不用影响其他类了。
好,那我们开始使用合成/聚合的桥接模式来设计一次架构。
public abstract class PlatformSoft
{
public abstract void Run();
}

//平台游戏
public class PlatformGame : PlatformSoft
{
public override void Run()
{
Console.WriteLine("运行游戏功能");
}
}

//平台社区
public class PlatformAPP : PlatformSoft
{
public override void Run()
{
Console.WriteLine("运行社区功能");
}
}

//各个平台类
public abstract class Platform
{
public PlatformSoft Soft;

//设置运行的软件
public void SetPlatformSoft(PlatformSoft soft)
{
this.Soft = soft;
}
//运行
public abstract void Run();

}

//安卓平台
public class Android : Platform
{
public override void Run()
{
Console.Write("安卓平台");
Soft.Run();
}
}

//苹果平台
public class IOS : Platform
{
public override void Run()
{
Console.Write("苹果平台");
Soft.Run();
}
}
  在Main方法中运行一下 
Platform p;
p = new Android();
p.SetPlatformSoft(new PlatformAPP());
p.Run();
p.SetPlatformSoft(new PlatformGame());
p.Run();

p = new IOS();
p.SetPlatformSoft(new PlatformAPP());
p.Run();
p.SetPlatformSoft(new PlatformGame());
p.Run();
Console.ReadKey();
     运行效果:



   这一次我们的运行方法是不是变得更简便了,而且大大方便了后续的添加修改,我们只需要修改或者添加指定的类,而不会对其他子类或者父类产生影响。这就是我们使用桥接模式的好处,最后我们再来总结下Bridge桥接模式的几个要点。
   Bridge桥接模式使用"对象的组合关系"解耦了抽象和实现之间固有的绑定关系,使得抽象(平台)和实现(不同的功能)可以沿着各自的维度来变化。
   所谓的抽象和实现沿着各自维度的变化,即"子类化"他们,比如不同的平台子类,和不同的软件功能子类。得到各个子类之后,便可以任意组合他们,从而获得不同平台上的不同类型。
   Bridge桥接模式有时类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge桥接模式是比对继承方案更好的解决办法。
   Bridge桥接模式的应用一般在"两个非常强的变化维度",有时候即使只有两个变化的维度,但是某个方向的变化维度并不剧烈---换言之两个变化不会导致纵横交错的结果,
并一定要使用Bridge桥接模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity 设计模式