IronMan之桥接
前言
前面的几个篇幅都是在讲"部件"的生产已经简简单单的使用,以后可能要对"部件"进行升级,不是不对它本身升级,是其它方式的升级,可以让它配备武器。 有没有感觉"部件"是越来越强大了,事物的衍变都是有个过程的嘛,必须要越来越完善,这是"IronMan"设计的宗旨。
好了,废话不多说了,现在所要做的工作就是设计好这个"武器",以便在后面的篇幅中和"部件"很好的结合在一起。来看一下"武器"的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
1
/// <summary>
2
/// 武器
3
/// </summary>
4
public
abstract
class
Weapon
5 {
6
/// <summary>
7
/// 攻击
8
/// </summary>
9
public
abstract
void
Attack();
10 }
11
/// <summary>
12
/// 激光武器
13
/// </summary>
14
public
class
LaserWeapon : Weapon
15 {
16
17
public
override
void
Attack()
18 {
19
//LaserAttack
20 }
21 }
22
/// <summary>
23
/// 导弹武器
24
/// </summary>
25
public
class
MissileWeapon : Weapon
26 {
27
28
public
override
void
Attack()
29 {
30
//MissileAttack
31 }
32 }
|
这样看起来好像没有什么不妥的,因为出于设计的全面性和以便于以后的扩展,所以要尽可能的想的全面。
"武器"的使用也是要受环境限制或影响的。在这里怎么表现出来呢?
先假设两种坏境的下武器使用,一种是水下,一种是太空中(真空状态)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
1
/// <summary>
2
/// 水下的激光武器
3
/// </summary>
4
public
class
UnderwaterLaserWeapon : LaserWeapon
5 {
6
public
override
void
Attack()
7 {
8
//逻辑处理
9
base
.Attack();
10
//逻辑处理
11 }
12 }
13
/// <summary>
14
/// 真空状态下激光武器
15
/// </summary>
16
public
class
EmptyLaserWeapon : LaserWeapon
17 {
18
public
override
void
Attack()
19 {
20
//逻辑处理
21
base
.Attack();
22
//逻辑处理
23 }
24 }
25
/// <summary>
26
/// 水下的导弹武器
27
/// </summary>
28
public
class
UnderwaterMissileWeapon : MissileWeapon
29 {
30
public
override
void
Attack()
31 {
32
//逻辑处理
33
base
.Attack();
34
//逻辑处理
35 }
36 }
37
/// <summary>
38
/// 真空下的导弹武器
39
/// </summary>
40
public
class
EmptyMissileWeapon : MissileWeapon
41 {
42
public
override
void
Attack()
43 {
44
//逻辑处理
45
base
.Attack();
46
//逻辑处理
47 }
48 }
|
看一下图1所示现在所有类型的结构图
整体的设计是没有大碍的,在增加一项"武器"类型时也是没有问题了,同样遵循着开闭原则。
如果是在添加一种坏境的时候也是遵循着开闭原则的,但是违背了类的单一职责原则,而且这样的设计继承关系太多,不易维护难以扩展,如果这个"武器"是多维的,而且是同时的向着多维前面变化的,那么这个"武器"的结构将会变的庞大无比。
现在应该是"桥接"大展身手的时候了,要在"武器"的两个(或者更多)变化的方向解耦,把强耦合变成弱联系。
实现
原来"武器"的结构不变,只需要在其中的一个维度中提取出抽象(实现类接口),然后"武器"(抽象类)引用从维度中提取出的抽象就好了。
我们来看一下结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
1
/// <summary>
2
/// 环境
3
/// </summary>
4
public
interface
IEnvironment
5 {
6
/// <summary>
7
/// 环境抽象
8
/// </summary>
9
void
EnvironmentJudge();
10 }
11
/// <summary>
12
/// 水下环境的
13
/// </summary>
14
public
class
Underwater : IEnvironment
15 {
16
17
public
void
EnvironmentJudge()
18 {
19 Console.WriteLine(
"在水下的"
);
20 }
21 }
22
/// <summary>
23
/// 真空环境下的
24
/// </summary>
25
public
class
Empty : IEnvironment
26 {
27
28
public
void
EnvironmentJudge()
29 {
30 Console.WriteLine(
"真空下的"
);
31 }
32 }
|
上面是 环境维度的结构,下面来看"武器"类型维度的结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
1
/// <summary>
2
/// 武器
3
/// </summary>
4
public
abstract
class
Weapon
5 {
6
protected
IEnvironment Environment =
null
;
7
/// <summary>
8
/// 攻击
9
/// </summary>
10
public
abstract
void
Attack();
11 }
12
/// <summary>
13
/// 激光武器
14
/// </summary>
15
public
class
LaserWeapon : Weapon
16 {
17
public
LaserWeapon():
this
(
new
Underwater()) { }
//默认使用环境为水下
18
public
LaserWeapon(IEnvironment environment)
19 {
20
base
.Environment = environment;
21 }
22
public
override
void
Attack()
23 {
24
//LaserAttack
25
base
.Environment.EnvironmentJudge();
26 Console.WriteLine(
"激光武器"
);
27 }
28 }
29
/// <summary>
30
/// 导弹武器
31
/// </summary>
32
public
class
MissileWeapon : Weapon
33 {
34
public
MissileWeapon():
this
(
new
Underwater()) { }
35
public
MissileWeapon(IEnvironment environment)
36 {
37
base
.Environment = environment;
38 }
39
public
override
void
Attack()
40 {
41
//MissileAttack
42
base
.Environment.EnvironmentJudge();
43 Console.WriteLine(
"导弹武器"
);
44 }
45 }
|
如图2的所示现在的对象结构:
类型都已经定义完成了,现在来看一下客户端调用代码:
1
2
3
|
1
//Weapon weapon = new LaserWeapon();//这里已经默认的是水下坏境了
2 Weapon weapon =
new
MissileWeapon(
new
Empty());
3 weapon.Attack();
|
结果如图3所示:
桥接模式就讲到这里. 下一个篇幅将讲到怎么把"武器"安装到"部件"上使用的“装饰者模式”。
本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1412172,如需转载请自行联系原作者