设计模式之桥接模式(Bridge)
1.引言
一位哲学家说“你永远也看不到一条一模一样的河”,不考虑哲学上的对错,光是从变化的角度看,的确是这样,因为尽管一条小河,在空间上没有发生变化,但在时间坐标上已经发生了改变,世上万物都在做着这样的变化,但是你把一块石头放在你的鱼缸里面,几天后,你会发现它还是那块石头,这说明事物尽管都有向多个维度变化的特性,但是有些事物是相对比较稳定的,而有些事物多维度变化确实比较激励的。我们用继承(inherit)解决了变化不稳定的事物的扩展问题,如何利用面向对象的技术来使得事物能够轻松的沿着多个方向进行变化,实现起来又不是很复杂呢?这就要使用Bridge模式。
2)意图
使抽象部分和实现部分分离,使他们都能够独立的变化(GOF)
采用继承的情况下,具体实现依赖于抽象定义,抽象定义被看作是相对稳定的。而对于像多个维度变化激烈的对象来说 ,抽象定义也是不稳定的。这时候,如果想尽可能付出小的代价,获得最大的扩展,采用桥接模式是一个好的主意
3)结构图
4)以坦克大战中的坦克为例,说明桥接模式的优点
实例代码为:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace BridgeStudy
6
{
7
/// <summary>
8
/// 坦克基类
9
/// </summary>
10
public abstract class TankBase
11
{
12
TankBase1 tank = null;
13
public TankBase1 Tank
14
{
15
get
16
{
17
return tank;
18
}
19
set
20
{
21
tank = value;
22
}
23
}
24
25
public TankBase1 TankBase1
26
{
27
get
28
{
29
throw new System.NotImplementedException();
30
}
31
set
32
{
33
}
34
}
35
36
public virtual void Shoot()
37
{
38
tank.Shoot();
39
}
40
}
41
}
42

1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace BridgeStudy
6
{
7
/// <summary>
8
/// 射击炮弹种类不同的坦克基类
9
/// </summary>
10
public abstract class TankBase1
11
{
12
13
public abstract void Shoot();
14
}
15
}
16

1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace BridgeStudy
6
{
7
/// <summary>
8
/// 纵向射击坦克的实现类
9
/// </summary>
10
public class VerticalTank:TankBase
11
{
12
public override void Shoot()
13
{
14
base.Shoot();
15
Console.WriteLine("shoot vertical
");
16
}
17
}
18
}
19
20
using System;
21
using System.Collections.Generic;
22
using System.Text;
23
24
namespace BridgeStudy
25
{
26
/// <summary>
27
/// 横向设计坦克的实现类
28
/// </summary>
29
public class HorizontalTank : TankBase
30
{
31
public override void Shoot()
32
{
33
base.Shoot();
34
Console.WriteLine("shoot horizontal
");
35
}
36
}
37
}
38

1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace BridgeStudy
6
{
7
/// <summary>
8
/// 普通炮弹坦克实现类
9
/// </summary>
10
public class CommonTank : TankBase1
11
{
12
public override void Shoot()
13
{
14
Console.WriteLine("shoot common cannonball
");
15
}
16
}
17
}
18
19
20
using System;
21
using System.Collections.Generic;
22
using System.Text;
23
24
namespace BridgeStudy
25
{
26
/// <summary>
27
/// 激光坦克实现类
28
/// </summary>
29
public class LaserTank:TankBase1
30
{
31
public override void Shoot()
32
{
33
Console.WriteLine("shoot common Laser
");
34
}
35
}
36
}
37
类关系图为
运行结果:
源代码:/Files/jillzhang/BridgeStudy.rar
总结:
1。Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
一位哲学家说“你永远也看不到一条一模一样的河”,不考虑哲学上的对错,光是从变化的角度看,的确是这样,因为尽管一条小河,在空间上没有发生变化,但在时间坐标上已经发生了改变,世上万物都在做着这样的变化,但是你把一块石头放在你的鱼缸里面,几天后,你会发现它还是那块石头,这说明事物尽管都有向多个维度变化的特性,但是有些事物是相对比较稳定的,而有些事物多维度变化确实比较激励的。我们用继承(inherit)解决了变化不稳定的事物的扩展问题,如何利用面向对象的技术来使得事物能够轻松的沿着多个方向进行变化,实现起来又不是很复杂呢?这就要使用Bridge模式。
2)意图
使抽象部分和实现部分分离,使他们都能够独立的变化(GOF)
采用继承的情况下,具体实现依赖于抽象定义,抽象定义被看作是相对稳定的。而对于像多个维度变化激烈的对象来说 ,抽象定义也是不稳定的。这时候,如果想尽可能付出小的代价,获得最大的扩展,采用桥接模式是一个好的主意
3)结构图
4)以坦克大战中的坦克为例,说明桥接模式的优点
实例代码为:
1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace BridgeStudy6
{7
/// <summary>8
/// 坦克基类9
/// </summary>10
public abstract class TankBase11
{12
TankBase1 tank = null;13
public TankBase1 Tank14
{15
get16
{17
return tank;18
}19
set20
{21
tank = value;22
}23
}24

25
public TankBase1 TankBase126
{27
get28
{29
throw new System.NotImplementedException();30
}31
set32
{33
}34
}35
36
public virtual void Shoot()37
{38
tank.Shoot();39
}40
}41
}42

1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace BridgeStudy6
{7
/// <summary>8
/// 射击炮弹种类不同的坦克基类9
/// </summary>10
public abstract class TankBase111
{12
13
public abstract void Shoot();14
}15
}16

1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace BridgeStudy6
{7
/// <summary>8
/// 纵向射击坦克的实现类9
/// </summary>10
public class VerticalTank:TankBase11
{ 12
public override void Shoot()13
{14
base.Shoot();15
Console.WriteLine("shoot vertical
");16
}17
}18
}19

20
using System;21
using System.Collections.Generic;22
using System.Text;23

24
namespace BridgeStudy25
{26
/// <summary>27
/// 横向设计坦克的实现类28
/// </summary>29
public class HorizontalTank : TankBase30
{ 31
public override void Shoot()32
{33
base.Shoot();34
Console.WriteLine("shoot horizontal
");35
}36
}37
}38

1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace BridgeStudy6
{7
/// <summary>8
/// 普通炮弹坦克实现类9
/// </summary>10
public class CommonTank : TankBase111
{12
public override void Shoot()13
{14
Console.WriteLine("shoot common cannonball
");15
}16
}17
}18

19

20
using System;21
using System.Collections.Generic;22
using System.Text;23

24
namespace BridgeStudy25
{26
/// <summary>27
/// 激光坦克实现类28
/// </summary>29
public class LaserTank:TankBase130
{31
public override void Shoot()32
{33
Console.WriteLine("shoot common Laser
");34
}35
}36
}37

运行结果:
源代码:/Files/jillzhang/BridgeStudy.rar
总结:
1。Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同平台上的不同型号。
3.Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
4.Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。
适用性
在以下的情况下应当使用桥梁模式:
1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
2.设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
3.一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
4.虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则。
关于桥接模式更好,更详细的介绍请访问.NET设计模式(9):桥接模式(Bridge
Pattern)


浙公网安备 33010602011771号