本文介绍 桥 模式,参考了 https://www.bilibili.com/video/BV1Yr4y157Ci
目的
由于某些类型的固有实现逻辑,使得它们具有多个变化的纬度。
示例
1
2
3
4
5
6
7
8
9
10
11
12
| class Messager {
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(Image image) = 0;
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~Messager() {}
};
|
那么我们可能会需要考虑很多平台的实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| class PCMessagerBase : public Messager {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MobileMessagerBase : public Messager {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
|
我们可能要推出精简版,或者完美版
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
| class PCMessagerLite : public PCMessagerBase {
public:
virtual void Login(string username, string password) {
PCMessagerBase::Connect();
// ...
}
virtual void SendMessage(string message) {
PCMessagerBase::WriteText();
// ...
}
virtual void SendPicture(Image image) {
PCMessagerBase::DrawShape();
// ...
}
};
class PCMessagerPerfect : public PCMessagerBase {
public:
virtual void Login(string username, string password) {
PCMessagerBase::PlaySound();
PCMessagerBase::Connect();
// ...
}
virtual void SendMessage(string message) {
PCMessagerBase::PlaySound();
PCMessagerBase::WriteText();
// ...
}
virtual void SendPicture(Image image) {
PCMessagerBase::PlaySound();
PCMessagerBase::DrawShape();
// ...
}
};
|
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
| class MobileMessagerLite : public PCMessagerBase {
public:
virtual void Login(string username, string password) {
MobileMessagerBase::Connect();
// ...
}
virtual void SendMessage(string message) {
MobileMessagerBase::WriteText();
// ...
}
virtual void SendPicture(Image image) {
MobileMessagerBase::DrawShape();
// ...
}
};
class MobileMessagerPerfect : public PCMessagerBase {
public:
virtual void Login(string username, string password) {
MobileMessagerBase::PlaySound();
MobileMessagerBase::Connect();
// ...
}
virtual void SendMessage(string message) {
MobileMessagerBase::PlaySound();
MobileMessagerBase::WriteText();
// ...
}
virtual void SendPicture(Image image) {
MobileMessagerBase::PlaySound();
MobileMessagerBase::DrawShape();
// ...
}
};
|
那么我使用时就需要
1
2
3
| void Process() {
Messager *m = new MobileMessagerPerfect();
}
|
如果我们的抽象多了,那么类的数目又会增加很快。何况这些类里面重复的东西又很多。
如果我们使用装饰器模式中的继承转为组合,会好吗?可以。
我们可以合并 MessagerLite 类 和 MessagerPerfect 类,但会出现问题,因为两个 fooBase 的基类有问题,它是一个抽象类,因为没有全部实现基类接口,所以问题出现在 Messager 类上。参考如下代码
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
| class Messager {
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(Image image) = 0;
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~Messager() {}
};
class PCMessagerBase : public Messager {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MobileMessagerBase : public Messager {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MessagerLite {
Messager* messager;
public:
virtual void Login(string username, string password) {
messager->Connect();
// ...
}
virtual void SendMessage(string message) {
messager->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messager->DrawShape();
// ...
}
};
class MessagerPerfect {
Messager* messager; // = new PCMessagerBase/MobileMessagerBase
public:
virtual void Login(string username, string password) {
messager->PlaySound();
messager->Connect();
// ...
}
virtual void SendMessage(string message) {
messager->PlaySound();
messager->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messager->PlaySound();
messager->DrawShape();
// ...
}
};
|
我们可以把它拆开,然后再正确的继承
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| class Messager {
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(Image image) = 0;
virtual ~Messager() {}
};
class MessagerImpl {
public:
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~MessagerImpl() {}
};
class PCMessagerBase : public MessagerImpl {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MobileMessagerBase : public MessagerImpl {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MessagerLite : public Messager {
MessagerImpl* messager;
public:
virtual void Login(string username, string password) {
messagerImpl->Connect();
// ...
}
virtual void SendMessage(string message) {
messagerImpl->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messagerImpl->DrawShape();
// ...
}
};
class MessagerPerfect : public Messager {
MessagerImpl* messagerImpl; // = new PCMessagerBase/MobileMessagerBase
public:
virtual void Login(string username, string password) {
messagerImpl->PlaySound();
messagerImpl->Connect();
// ...
}
virtual void SendMessage(string message) {
messagerImpl->PlaySound();
messagerImpl->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messagerImpl->PlaySound();
messagerImpl->DrawShape();
// ...
}
};
|
之后可以再提一次:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| class Messager {
protected:
MessagerImpl* messagerImpl;
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(Image image) = 0;
virtual ~Messager() {}
};
class MessagerImpl {
public:
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~MessagerImpl() {}
};
class PCMessagerImpl : public MessagerImpl {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MobileMessagerImpl : public MessagerImpl {
public:
virtual void PlaySound() {}
virtual void DrawShape() {}
virtual void WriteText() {}
virtual void Connect() {}
};
class MessagerLite : public Messager {
public:
virtual void Login(string username, string password) {
messagerImpl->Connect();
// ...
}
virtual void SendMessage(string message) {
messagerImpl->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messagerImpl->DrawShape();
// ...
}
};
class MessagerPerfect : public Messager {
public:
virtual void Login(string username, string password) {
messagerImpl->PlaySound();
messagerImpl->Connect();
// ...
}
virtual void SendMessage(string message) {
messagerImpl->PlaySound();
messagerImpl->WriteText();
// ...
}
virtual void SendPicture(Image image) {
messagerImpl->PlaySound();
messagerImpl->DrawShape();
// ...
}
};
|
此外修改一下构造函数即可,委托给父类。
1
2
| MessagerImpl* imp = new PCMessagerImpl();
Messager* m = new MessagerLite(imp);
|
桥模式
将抽象部分(业务)与实现部分(平台实现)分离,使得它们可以独立变化。