以下笔记摘录自李建忠老师的<<c++设计模式>>和书籍<<设计模式>>

动机

  • 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。

定义

  • 将抽象部分(业务功能)与实现部分(平台兼容)分离,使他们都可以独立的变化。

原始代码

  • 抽象类中包含了两个维度的接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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();
//........
}
};

class MobileMessagerLite : public MobileMessagerBase {
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 MobileMessagerBase {
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
4
void Process(){
//编译时装配
Messager *m = new MobileMessagerPerfect();
}

重构代码

  • 抽象类中包含了两个维度的接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class Messager{
    protected:
    MessagerImp * messageImp;
    public:
    Messager(MessagerImp *imp) : messageImp(imp) {}
    virtual void Login(string username, string password)=0;
    virtual void SendMessage(string message)=0;
    virtual void SendPicture(Image image)=0;

    virtual ~Messager(){}
    };
    class MessagerImp{
    public:
    virtual void PlaySound()=0;
    virtual void DrawShape()=0;
    virtual void WriteText()=0;
    virtual void Connect()=0;

    virtual ~MessagerImp(){}
    };
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
class PCMessagerImp : public MessagerImp{
public:
virtual void PlaySound(){
//**********
}
virtual void DrawShape(){
//**********
}
virtual void WriteText(){
//**********
}
virtual void Connect(){
//**********
}
};

class MobileMessagerImp : public MessagerImp{
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
35
36
37
38
39
class MessagerLite : public Messager {
public:
MessagerLite(MessagerImp* mImp) : Messager(mImp) {}
virtual void Login(string username, string password){
messageImp->Connect();
//........
}
virtual void SendMessage(string message){
messageImp->CWriteText();
//........
}
virtual void SendPicture(Image image){
messageImp->CDrawShape();
//........
}
};

class MessagerPerfect : public Messager {
public:
MessagerPerfect(MessagerImp* mImp) : Messager(mImp) {}
virtual void Login(string username, string password){
messageImp->CPlaySound();
//********
messageImp->CConnect();
//........
}
virtual void SendMessage(string message){
messageImp->CPlaySound();
//********
messageImp->CWriteText();
//........
}
virtual void SendPicture(Image image){
messageImp->CPlaySound();
//********
messageImp->CDrawShape();
//........
}
};
  • 这里也可以通过抽象工厂自动完成Imp的实现
    1
    2
    3
    4
    5
    6
    void Process(){
    //运行时装配
    MessagerImp* mImp=new PCMessagerImp();
    MessagerLite *mp =new MessagerLite(mImp);
    MessagerPerfect *ml =new MessagerPerfect(mImp);
    }

总结

  • 结构图