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://blog.csdn.net/solomon1/article/details/2005156