本文共 2103 字,大约阅读时间需要 7 分钟。
MFC与设计模式
本文主要讨论三个设计模式在MFC中的应用。 这三个设计模式分别为:单件、桥和观察者模式。
一。创建型:单件模式(Singleton)
任何MFC应用程序首先创建一个应用程序对象(一个继承自CWinApp类的类的对象),一个MFC程序实例只能有一个应用程序对象。只能创建一个对象的机制由CWinApp来保证。在CWinApp的构造函数中有如下语句:
ASSERT(AfxGetThread() == NULL);
如果你定义了两个应用程序对象,第一个构造CWinApp时满足AfxGetThread() == NULL,而构造第二个对象时就会失败。
这与我们最常见的经典单件模式的实现有点不一样,最常见的是把构造函数设计为protected,再提供一个public静态类型的创建对象的方法。一个简单的实例如下(C++实现):
// h 声明文件 class CSingleton { public: static CSingleton* CreateInstance(); // 要创建对象只能调用这个函数 int DestroyInstance(); // 删除时调用这个 protected: CSingleton(); // 把构造函数和析构设计成保护,外面就不能直接声明对象或者new一个对象了 ~CSingleton(); protected: static int m__sCountRef; // 实例应用计数 static CSingleton* m_pInstance; // 实例指针 }; // CPP实现文件 // 先初始化静态成员 int CSingleton::m__sCountRef = 0; CSingleton* CSingleton::m_pInstance = 0; CSingleton* CSingleton::CreateInstance() { if (0 == m__sCountRef) { //ASSERT(NULL == m_pInstance); m_pInstance = new CSingleton; } m__sCountRef++; return m_pInstance; } int CSingleton::DestroyInstance() { m__sCountRef--; if (0 == m__sCountRef) { delete m_pInstance; m_pInstance = 0; } return 0; } CSingleton::CSingleton() { } CSingleton::~CSingleton() { } 从上可以看出,单件模式的实现方法是多样的,设计模式是一种抽象,一种设计思想,具体实现可以有所不同。由单件模式还可以演化出双件模式等。
二.结构型 :桥模式(Bridge)
桥模式是一种关于解藕抽象和实现的模式,可以实现抽象和实现的独立变化。在MFC中,对文件的I/O操作过程称作串行化。MFC使用了桥模式来实现串行化。CArcive和CFile类实现了文件的串行化,CArchive类提供读写永久机制对象的接口,CFile类及其子类实现了不同的永久机制,例如:内存、磁盘和网络套接字等。
一个CArchive对象在构造时就和一个CFile类联系在一起了,以获取必须的串行化信息,包括文件名、读写操作类型等。客户执行串行化操作时使用CArchive对象,而不用关心用CFile类实现的永久性机制。
Bridge is here
CArchive<------------------------------------CFile
(CArchive使用CFile,客户使用CArchive) |
------------------------
| | |
CMemFile CMirrorFile SocketFile
桥模式的优点:
1)解藕抽象和实现;
2)提高了可扩展性,抽象和实现可以独立变化;
3)减少了子类的数目;
4)减小了与客户代码的耦合;
三.行为型 : 观察者模式
观察者模式是一种处理多对象间“一对多”关系的设计模式,当一个对象的状态变化,其他对象的状态能得到自动更新。“一对多”中的“一”称作“目标角色”,“多”称作“观察者”。
MFC中著名的的文档/视图结构就是一种观察者模式的实现,文档包含了数据对象,扮演目标角色。一个视图是一个窗口对象,用户通过它更新文档数据,扮演观察者角色。一个文档可以有多个视图,不管什么时候文档被其中任何一个视图改变后,它将调用UpdateAllViews通知每个视图。视图的派生类可以重写OnUpdate 方法以通过查询文档数据来更新自己。
CView在创建对象时(OnCreate)会调用AddView把自己加入到CDocument的视图列表(m_viewList)中,当CDocument的数据改变需要通知视图对象时,它就会调用视图列表(m_viewList)中的每个视图对象的OnUpdate方法以更新视图。
转载地址:http://qtvpi.baihongyu.com/