以下笔记摘录自李建忠老师的<<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); }
|
总结
- 结构图
