设计模式之桥接模式
桥接模式,将抽象部分与它的实现部分分离,使它们都可以独立地变化。这里说的实现分离,并不是说然抽象类与派生类分离,这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。其UML图如下:
结合上图理解一下其定义。抽象部分指的是Abstraction或者RefinedAbstraction。实现部分指的是Implementor。以为抽象部分得实现有多种变化,为了减少耦合,所以把实现部分得变化封装起来,通过组合得方式实现。这就是定义中说得将抽象部分与它得实现部分分离。而定义中说得实现指得是抽象类和它得派生类用来实现自己得对象就是对变化封装后得类,即Implementor。举个例子就很好理解啦。就拿电脑来举例子吧。电脑又有微软得电脑,联想得电脑。而电脑上可以运行游戏,也可以运行记事本等软件。有两种方式可以实现电脑产品,如下:
方式一:
这种方式耦合性太高,比如像添加一种软件,需要添加微软电脑的软件和联想电脑的软件。同样的像添加一种电脑,也要添加相应的软件。如果要修改一种软件,则要修改很多软件。
方式二,那就是电脑是电脑,软件是软件两者分离。如下图:
很明显方式二耦合性底,容易维护和扩展。这里电脑就相当于抽线,而软件则相当于实现。总的来说就是桥接模式主要是实现系统可能有多个角度分类,每一种分类都有可能变化。那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
以电脑和软件为例其示例代码如下:
1 // BridgeModel.h文件
2 #pragma once
3 #include <iostream>
4
5 class Software
6 {
7 public:
8 virtual void run() = 0;
9 };
10
11 class SoftwareGame : public Software
12 {
13 public:
14 void run()
15 {
16 std::cout << "游戏软件" << std::endl;
17 }
18 };
19
20 class SoftwareNote : public Software
21 {
22 public:
23 void run()
24 {
25 std::cout << "记事本软件" << std::endl;
26 }
27 };
28 //
29 class Computer
30 {
31 protected:
32 Software * m_software;
33 public:
34 Computer() : m_software(nullptr){}
35 virtual ~Computer()
36 {
37 if (nullptr == m_software)
38 delete m_software;
39 }
40 virtual void run() = 0;
41 void setSoftware(Software *p)
42 {
43 m_software = p;
44 }
45 };
46
47 class ComputerLenovo : public Computer
48 {
49 public:
50 void run()
51 {
52 std::cout << "联想的电脑运行";
53 m_software->run();
54 }
55 };
56
57 class ComputerMirco : public Computer
58 {
59 public:
60 void run()
61 {
62 std::cout << "微软的电脑运行";
63 m_software->run();
64 }
65 };
测试代码如下:
1 #include <iostream>
2 #include "BridgeModel.h"
3
4 int main()
5 {
6 using namespace std;
7 // 桥接模式
8 Computer *p = new ComputerLenovo();
9 p->setSoftware(new SoftwareGame());
10 p->run();
11 delete p;
12
13 p = new ComputerMirco();
14 p->setSoftware(new SoftwareNote());
15 p->run();
16 delete p;
17
18 getchar();
19 return 0;
20 }
测试结果如下图: