Design Patterns之Bridge Pattern学习总结
今晚看了Bridge模式,本想总结时再自己想个例子,不过没有想到,于是就引用李建忠老师的C#设计模式之Bridge模式中的坦克例子吧,加深一下理解。文中要是有不对的地方还请大家指点。
Bidge模式,是为了应对多维度的变化的情况,先不管那么多,例子先上。
假设现在要开发一个平常玩的那种坦克游戏,但这个游戏要有两个版本,PC版的和手机版的,其中坦克有许多型号,但PC版所有的坦克,手机版中也要有,而且功能要完全相同的,要不然就太不公平,玩的没意思了,但是PC版和手机版的实现肯定是有所不同的,硬件性能相差那么大,PC版的坦克外观可能会是非常逼真的3D效果,但手机版的可能只是二维的。
于是,我就画出了下面这张图:

其中Tank是一个抽象基类,其中假设有Shoot(),Move(),Stop(),Turn()方法,分别表示射击、移动、停住、转弯,而T50和T75是两个型号的坦克,都继承于Tank,它们将实现具体的方法。但我们是要有PC和Mobile两个平台的,于是又有了PC版的T50:PCT50,PC版的T50:MobileT50,T75也一样,有两个平台。
实现代码:
Code
这么做乍看起来是挺合理的,但是,如果我们要再加一个型号T80呢?那还要再来一个T80继承Tank,PCT80和MobileT80再继承T80,如果要增加很多的型号,那我们就要这么写很多个类,更关键的是,PC平台和Mobile平台上的坦克的功能是完全一样的,比如他们的发炮方法,转弯方法,所以,我们在PCT50和MobileT50中难免会有重复的代码,PCT75和MobileT75中也会有,那我们不是可以拷贝代码吗?当然可以,但这绝对不是好办法,而且当我们要增加其它的平台,那工作量又得大增。另外,对于PCT50和MobileT50这些类,坦克的功能会引起它们变化,具体平台的变化也会引起它们变化,而我们说,一个类应该只有一个引起它变化的原因。
看上面的这个设计,对于一辆坦克,它有两个维度的变化,一个是不同型号坦克的不同战斗方式,一个是不同平台的不同实现。所以这时候,我们用Bridge模式,让型号和平台独立变化,不要这样揉在一起。

如上图,TankPlatform描述平台, 它有一个属性PlatformName,指平台名称,在PCPlatform和MobilePlatform的构造方法中将初始化这个值,它的DrawTank()和DrawShell()方法表示了不同平台上绘制坦克和炮弹的方法,PCPlatform和MobilePlatform继承TankPlatform,表示PC平台和Mobile平台。Tank有一个TankPlatform类型的protected字段platform,它表示坦克所运行的平台,T50和T75继承于Tank。
附上用了Bridge模式后的代码:
Code
然后就可以在Main方法中测试一下:
Code
输出:
PC Platform T50 Shoot
PC Platform T50 Move
Mobile Platform T75 Stop
Mobile Platform T75 Turn
这样子的设计有什么优点呢?从效果上来看:如果我们要增加其它型号的坦克,比如T80,那我们只要写一个T80继承Tank,实现它的4个功能即可,不需要再在T80中掺入任何平台相关的东西,而当我们要增加其它平台时,我们也只要写一个具体平台类继承TankPlatform,也不需要重新写射击、转弯等方法。这样一来,平台和坦克功能之间的耦合度就低得多了,也不会违背单一职责的原则了。
现在再来看我们的Bridge模式,它让前面说的两维度的变化各自变去,让它们不揉在一起了。而对于Bridge模式的名字“Bridge”的起源,也许就是因为它作为这多维度之间联系的桥梁吧,比如例子中Tank的platform字段就是这个bridge(桥)。同时,我们也可以看到对象组合的应用是很广泛的。
小感触
自从开始看设计模式之后,我才发现原来编程可以这么艺术,我也发觉自己当初有多么愚昧,以为软件的核心就是算法。虽然我不是很聪明,没有太多的天赋,但我相信,努力一定会有收获的。同时还要感谢李建忠老师的设计模式WebCast,是它让我第一次意识到我从前写的程序有多么弱智(尽管我现在的程序还是很弱智,但至少比起以前好多了
)。
Bidge模式,是为了应对多维度的变化的情况,先不管那么多,例子先上。
假设现在要开发一个平常玩的那种坦克游戏,但这个游戏要有两个版本,PC版的和手机版的,其中坦克有许多型号,但PC版所有的坦克,手机版中也要有,而且功能要完全相同的,要不然就太不公平,玩的没意思了,但是PC版和手机版的实现肯定是有所不同的,硬件性能相差那么大,PC版的坦克外观可能会是非常逼真的3D效果,但手机版的可能只是二维的。
于是,我就画出了下面这张图:

实现代码:

这么做乍看起来是挺合理的,但是,如果我们要再加一个型号T80呢?那还要再来一个T80继承Tank,PCT80和MobileT80再继承T80,如果要增加很多的型号,那我们就要这么写很多个类,更关键的是,PC平台和Mobile平台上的坦克的功能是完全一样的,比如他们的发炮方法,转弯方法,所以,我们在PCT50和MobileT50中难免会有重复的代码,PCT75和MobileT75中也会有,那我们不是可以拷贝代码吗?当然可以,但这绝对不是好办法,而且当我们要增加其它的平台,那工作量又得大增。另外,对于PCT50和MobileT50这些类,坦克的功能会引起它们变化,具体平台的变化也会引起它们变化,而我们说,一个类应该只有一个引起它变化的原因。
看上面的这个设计,对于一辆坦克,它有两个维度的变化,一个是不同型号坦克的不同战斗方式,一个是不同平台的不同实现。所以这时候,我们用Bridge模式,让型号和平台独立变化,不要这样揉在一起。

如上图,TankPlatform描述平台, 它有一个属性PlatformName,指平台名称,在PCPlatform和MobilePlatform的构造方法中将初始化这个值,它的DrawTank()和DrawShell()方法表示了不同平台上绘制坦克和炮弹的方法,PCPlatform和MobilePlatform继承TankPlatform,表示PC平台和Mobile平台。Tank有一个TankPlatform类型的protected字段platform,它表示坦克所运行的平台,T50和T75继承于Tank。
附上用了Bridge模式后的代码:

然后就可以在Main方法中测试一下:

输出:
PC Platform T50 Shoot
PC Platform T50 Move
Mobile Platform T75 Stop
Mobile Platform T75 Turn
这样子的设计有什么优点呢?从效果上来看:如果我们要增加其它型号的坦克,比如T80,那我们只要写一个T80继承Tank,实现它的4个功能即可,不需要再在T80中掺入任何平台相关的东西,而当我们要增加其它平台时,我们也只要写一个具体平台类继承TankPlatform,也不需要重新写射击、转弯等方法。这样一来,平台和坦克功能之间的耦合度就低得多了,也不会违背单一职责的原则了。
现在再来看我们的Bridge模式,它让前面说的两维度的变化各自变去,让它们不揉在一起了。而对于Bridge模式的名字“Bridge”的起源,也许就是因为它作为这多维度之间联系的桥梁吧,比如例子中Tank的platform字段就是这个bridge(桥)。同时,我们也可以看到对象组合的应用是很广泛的。
小感触
自从开始看设计模式之后,我才发现原来编程可以这么艺术,我也发觉自己当初有多么愚昧,以为软件的核心就是算法。虽然我不是很聪明,没有太多的天赋,但我相信,努力一定会有收获的。同时还要感谢李建忠老师的设计模式WebCast,是它让我第一次意识到我从前写的程序有多么弱智(尽管我现在的程序还是很弱智,但至少比起以前好多了

分类:
Design Patterns
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架