首页
网站模板
整站模板
站群模板
应用中心
站群模板
插件
整站
建站软件
解决方案
帮助中心
教程中心
建站论坛
您现在的位置:
365建站网
>
365文章
> Design Patterns之Bridge Pattern学习总结
Design Patterns之Bridge Pattern学习总结
文章来源:365jz.com 点击数:
444
更新时间:2009-09-19 10:40
参与评论
今晚看了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
public
abstract
class
Tank
{
public
abstract
void
Shoot();
public
abstract
void
Move();
public
abstract
void
Stop();
public
abstract
void
Turn();
}
//
T50型坦克
public
class
T50 : Tank
{
public
override
void
Shoot()
{
Console.WriteLine(
"
T50 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
T50 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
T50 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
T50 Turn
"
);
}
}
//
T75型坦克
public
class
T75 : Tank
{
public
override
void
Shoot()
{
Console.WriteLine(
"
T75 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
T75 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
T75 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
T75 Turn
"
);
}
}
//
PC平台上的T50型坦克
public
class
PCT50 : T50
{
public
override
void
Shoot()
{
Console.WriteLine(
"
PC T50 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
PC T50 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
PC T50 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
PC T50 Turn
"
);
}
}
//
PC平台上的T75型坦克
public
class
PCT75 : T75
{
public
override
void
Shoot()
{
Console.WriteLine(
"
PC T75 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
PC T75 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
PC T75 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
PC T75 Turn
"
);
}
}
//
Mobile平台上的T50型坦克
public
class
MobileT50 : T50
{
public
override
void
Shoot()
{
Console.WriteLine(
"
Mobile T50 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
Mobile T50 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
Mobile T50 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
Mobile T50 Turn
"
);
}
}
//
Mobile平台上的T75型坦克
public
class
MobileT75 : T75
{
public
override
void
Shoot()
{
Console.WriteLine(
"
Mobile T75 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(
"
Mobile T75 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(
"
Mobile T75 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(
"
Mobile T75 Turn
"
);
}
}
这么做乍看起来是挺合理的,但是,如果我们要再加一个型号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
//
坦克抽象基类
public
abstract
class
Tank
{
protected
TankPlatform platform;
public
abstract
void
Shoot();
public
abstract
void
Move();
public
abstract
void
Stop();
public
abstract
void
Turn();
}
//
坦克所处平台的抽象基类
public
abstract
class
TankPlatform
{
protected
string
platformName;
public
abstract
string
PlatformName
{
get
;
}
public
abstract
void
DrawTank();
public
abstract
void
DrawShell();
}
//
PC平台
public
class
PCPlatform : TankPlatform
{
public
override
string
PlatformName
{
get
{
return
platformName; }
}
public
PCPlatform()
{
platformName
=
"
PC Platform
"
;
}
public
override
void
DrawTank()
{ }
public
override
void
DrawShell()
{ }
}
//
Mobile平台
public
class
MobilePlatform : TankPlatform
{
public
override
string
PlatformName
{
get
{
return
platformName; }
}
public
MobilePlatform()
{
platformName
=
"
Mobile Platform
"
;
}
public
override
void
DrawTank()
{ }
public
override
void
DrawShell()
{ }
}
//
T50型坦克
public
class
T50 : Tank
{
public
T50(TankPlatform platform)
{
this
.platform
=
platform;
}
public
override
void
Shoot()
{
Console.WriteLine(platform.PlatformName
+
"
T50 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(platform.PlatformName
+
"
T50 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(platform.PlatformName
+
"
T50 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(platform.PlatformName
+
"
T50 Turn
"
);
}
}
//
T75型坦克
public
class
T75 : Tank
{
public
T75(TankPlatform platform)
{
this
.platform
=
platform;
}
public
override
void
Shoot()
{
Console.WriteLine(platform.PlatformName
+
"
T75 Shoot
"
);
}
public
override
void
Move()
{
Console.WriteLine(platform.PlatformName
+
"
T75 Move
"
);
}
public
override
void
Stop()
{
Console.WriteLine(platform.PlatformName
+
"
T75 Stop
"
);
}
public
override
void
Turn()
{
Console.WriteLine(platform.PlatformName
+
"
T75 Turn
"
);
}
}
然后就可以在Main方法中测试一下:
Code
static
void
Main(
string
[] args)
{
PCPlatform pc
=
new
PCPlatform();
MobilePlatform m
=
new
MobilePlatform();
T50 pcT50
=
new
T50(pc);
pcT50.Shoot();
pcT50.Move();
T75 mT75
=
new
T75(m);
mT75.Stop();
mT75.Turn();
}
输出:
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,是它让我第一次意识到我从前写的程序有多么弱智(尽管我现在的程序还是很弱智,但至少比起以前好多了
)。
Tag标签: 设计模式,Design Patterns,模式,C#,.NET,Bridge Pattern,桥接模式
如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!!
点击进入论坛
您可能感兴趣的文章:
cefsharp devtools 截取节点屏幕截图 功能 vb.net代码
vb.net Application.ThreadException捕获程序自动退出事件代码
php session实例代码
php header 301跳转和302跳转代码
java通过session-timeout设置session不起作用的原因
发表评论
(
444
人查看
,
0
条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
提交评论
最新评论
------分隔线----------------------------
上一篇:
此页的状态信息无效,可能已损坏。”的解决办法
下一篇:
.NET 2.0项目常用错误的解决方法
大家感兴趣的内容
1
cefsharp devtools 截取节点屏幕截图 功能 vb.net代码
2
vb.net Application.ThreadException捕获程序自动退出事件代码
3
php session实例代码
4
php header 301跳转和302跳转代码
5
java通过session-timeout设置session不起作用的原因
6
什么是Cloudera公司的Impala查询系统
7
高斯函数(Gaussian function)的详细使用讲解
8
PHP获取文件的大小函数filesize()的用法和实例代码
9
html5 video的用法和实例代码
10
CSS中StyleSheet的用法和实例代码
最近更新的内容
1
jquery获取元素的所有宽高(包括边框 内边距和外边距)
2
复制移动整个文件夹php代码函数三种写法
3
cefsharp devtools 截取节点屏幕截图 功能 vb.net代码
4
vb.net Application.ThreadException捕获程序自动退出事件代码
5
http请求 412 Precondition Failed是什么
6
vb.net调用Microsoft.Office.Interop.Excel.dll 超过65536行报错解决方法
7
网站建设什么公司好
8
电脑画图软件有哪些
9
什么是ipc
10
epic是什么平台