意图
将抽象部分与他的实现部分分离,使他们都可以独立的变化
实现
参考我的这篇文章(点这里),之前已经总结过了,就不重复了。
注意:之前仅仅是对代码依赖性的考虑,这次是在之前的基础上增加了控制不同实现的效果
代码示例
注意:这是完整的示例代码 vs2013编译通过
//windows.h 文件
#pragma once
#include <iostream>
using namespace std;
//使用声明式 降低耦合
class WindowsImp;
class Windows
{
public:
Windows();
virtual ~Windows();
virtual void paint(){};
virtual void drawContents(){};
protected:
WindowsImp *getWindowImp();
private:
WindowsImp *m_imp;
};
class IcoWindows:public Windows
{
public:
IcoWindows();
~IcoWindows();
virtual void paint();
virtual void drawContents();
private:
//
};
class ButtonWindows :public Windows
{
public:
ButtonWindows();
~ButtonWindows();
virtual void paint();
virtual void drawContents();
private:
//
};
//windows.cpp 文件
#include "Windows.h"
#include "WindowsImp.h"
#include "WindowsFactory.h"
Windows::Windows()
:m_imp(NULL)
{
}
Windows::~Windows()
{
}
WindowsImp * Windows::getWindowImp()
{
if (m_imp==NULL)
{
m_imp = WindowsFactory::Instance()->getMicWinImp();
}
return m_imp;
}
IcoWindows::IcoWindows()
{
}
IcoWindows::~IcoWindows()
{
}
void IcoWindows::paint()
{
cout << "我是IcoWindows paint()" << endl;
//继承至父类,获取WindowsImp的实例
this->getWindowImp()->deviceRect();
return;
}
void IcoWindows::drawContents()
{
cout << "我是IcoWindows drawContents()" << endl;
this->getWindowImp()->paintBitmap();
return;
}
ButtonWindows::ButtonWindows()
{
}
ButtonWindows::~ButtonWindows()
{
}
void ButtonWindows::paint()
{
cout << "我是ButtonWindows paint()" << endl;
this->getWindowImp()->deviceRect();
return;
}
void ButtonWindows::drawContents()
{
cout << "我是ButtonWindows drawContents()" << endl;
this->getWindowImp()->paintBitmap();
return;
}
----------
//windowsImp.h 文件
#pragma once
#include <iostream>
using namespace std;
/*Windows 类的实现类 */
class WindowsImp
{
public:
virtual ~WindowsImp();
virtual void paintBitmap() = 0;
virtual void deviceRect() = 0;
protected:
WindowsImp();
};
//微软的版本
class MicrosoftWindowsImp:public WindowsImp
{
public:
MicrosoftWindowsImp();
~MicrosoftWindowsImp();
virtual void paintBitmap();
virtual void deviceRect();
private:
};
//苹果系统的版本
class AppleWindowsImp:public WindowsImp
{
public:
AppleWindowsImp();
~AppleWindowsImp();
virtual void paintBitmap();
virtual void deviceRect();
private:
};
//windowsImp.cpp 文件
#include "WindowsImp.h"
WindowsImp::WindowsImp()
{
}
WindowsImp::~WindowsImp()
{
}
MicrosoftWindowsImp::MicrosoftWindowsImp()
{
}
MicrosoftWindowsImp::~MicrosoftWindowsImp()
{
}
void MicrosoftWindowsImp::paintBitmap()
{
cout << "微软windows系统的 paintBitmap()" << endl;
return;
}
void MicrosoftWindowsImp::deviceRect()
{
cout << "微软windows系统的 deviceRect()" << endl;
}
AppleWindowsImp::AppleWindowsImp()
{
}
AppleWindowsImp::~AppleWindowsImp()
{
}
void AppleWindowsImp::paintBitmap()
{
cout << "苹果Mac系统的 paintBitmap()" << endl;
return;
}
void AppleWindowsImp::deviceRect()
{
cout << "苹果Mac系统的 deviceRect()" << endl;
return;
}
----------
//WindowsFactory.h文件
#pragma once
#include <iostream>
using namespace std;
class WindowsImp;
class MicrosoftWindowsImp;
class AppleWindowsImp;
class WindowsFactory
{
public:
WindowsFactory();
~WindowsFactory();
//工厂方法
WindowsImp * getMicWinImp(); //创建微软windows版本的实例
WindowsImp * getAppMacImp(); //创建苹果Mac版本的实例
/* 这里使用了 两个方法 来区分不同的系统版本对应的实现代码 */
/* 也可以通过宏定义 使用一个工厂方法就可以 自动的对应实现的代码 */
/* 也可以在创建Windows类的具体类的实例是 通过传入参数,来控制版本,总之方法很多 */
//单例模式
static WindowsFactory * Instance();
private:
static WindowsFactory *m_win;
MicrosoftWindowsImp * m_micWin;
AppleWindowsImp * m_appWin;
};
//WindowsFactory.cpp文件
#include "WindowsFactory.h"
#include "WindowsImp.h"
WindowsFactory::WindowsFactory()
:m_micWin(NULL), m_appWin(NULL)
{
}
WindowsFactory::~WindowsFactory()
{
}
WindowsImp * WindowsFactory::getMicWinImp()
{
if (m_micWin==NULL)
{
m_micWin = new MicrosoftWindowsImp();
}
return m_micWin;
}
WindowsImp * WindowsFactory::getAppMacImp()
{
if (m_appWin==NULL)
{
m_appWin = new AppleWindowsImp();
}
return m_appWin;
}
WindowsFactory * WindowsFactory::Instance()
{
if (m_win == NULL)
{
m_win = new WindowsFactory();
}
return m_win;
}
WindowsFactory * WindowsFactory::m_win=NULL;
----------
//main.cpp文件
#include "Windows.h"
int main()
{
IcoWindows ico;
ico.drawContents();
ico.paint();
cout << "\n------------------------\n" << endl;
ButtonWindows butt;
butt.drawContents();
butt.paint();
getchar();
return 0;
}
代码解析
- windows类是 窗口控件的抽象类 IcoWindows 类和 ButtonWIndows 类是他的具体子类,代表两种不同的控件
- windowsImp 类是 windows类的实现类 他的两个子类分别对应两个不同的实现版本
使用 windowsImpFactory 类的工厂方法来实例化 windowsImp 的子类
-windows类中的getWindowImp()方法来返回WindowsImp的实例
windowsImpFactory 类使用了 单例模式
文件依赖图
效果
- 分离了接口及其实现部分,降低编译的依赖性
- 提高了可扩充性
- 隐藏了实现细节
我的个人网站 http://www.breeziness.cn/
我的CSDN http://blog.csdn.net/qq_33775402转载请注明出处 小风code www.breeziness.cn