設計模式與XML(一)抽象工廠和反射機制(C++)
一、實驗目的及要求
1、掌握建立型模式的概念。
2、掌握工廠模式、抽象工廠模式、單例模式、建造者模式、原型模式的構造方式及使用情景。
二、實驗裝置(環境)
1、 軟體需求: Dev-Cpp5.4, Rational Rose / Microsoft Visio
2、 硬體需求: Pentium III 450以上的CPU處理器,1G以上的記憶體,2G的自由硬碟空間
三、實驗內容
1、蘋果的工廠(AppleFactory)生產手機(iPhoneX)和平板電腦(iPad),三星的工廠(SamsungFactory)生產手機(GalaxyNote)和平板電腦(GalaxyTab),用抽象工廠模式
2、(選做)實現C++的反射機制,使得:
(1) 增加新的具體工廠(如HuaweiFactory)和產品族很方便,無須修改已有系統,符合“開閉原則”。
(2)將具體工廠的類名寫入配置檔案中,通過反射機制,根據儲存在配置檔案中具體工廠的類名字串生成物件。即在客戶端(main函式)中不再使用具體工廠建立物件。
四、實驗步驟與結果
練習一
1、抽象工廠設計結構圖:
2、程式執行結果:
3、程式碼分析:
AbstractFactory.cpp
定義了抽象工廠AbstractFactory的方法,然後再定義兩個具體工廠AppleFactory和SamsungFactory的方法,分別在具體工廠中返回具體工廠生產的AbstractPhone產品iPhoneX、GalaxyNote和AbstractPad產品iPad、GalaxyTab的方法。
程式碼:
#include "AbstractFactory.h" #include "Product.h" #include <iostream> using namespace std; AbstractFactory::AbstractFactory() { } AbstractFactory::~AbstractFactory() { } AppleFactory::AppleFactory() { } AppleFactory::~AppleFactory() { } AbstractPhone* AppleFactory::CreatePhone() { return new iPhoneX(); } AbstractPad* AppleFactory::CreatePad() { return new iPad(); } SamsungFactory::SamsungFactory() { } SamsungFactory::~SamsungFactory() { } AbstractPhone* SamsungFactory::CreatePhone() { return new GalaxyNote(); } AbstractPad* SamsungFactory::CreatePad() { return new GalaxyTab(); }
AbstractFactory.h
定義了抽象工廠AbstractFactory的類,然後再定義兩個具體工廠AppleFactory和SamsungFactory的類。
程式碼:
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
class AbstractPhone;
class AbstractPad;
class AbstractFactory
{
public:
virtual ~AbstractFactory();
virtual AbstractPhone* CreatePhone() = 0;
virtual AbstractPad* CreatePad() = 0;
protected:
AbstractFactory();
private:
};
class AppleFactory:public AbstractFactory
{
public:
AppleFactory();
~AppleFactory();
AbstractPhone* CreatePhone();
AbstractPad* CreatePad();
protected:
private:
};
class SamsungFactory:public AbstractFactory
{
public:
SamsungFactory();
~SamsungFactory();
AbstractPhone* CreatePhone();
AbstractPad* CreatePad();
protected:
private:
};
#endif //~_ABSTRACTFACTORY_H_
Product.cpp
分別定義AbstractPhone產品iPhoneX、GalaxyNote和AbstractPad產品iPad、GalaxyTab的方法和輸出。
程式碼:
#include "Product.h"
#include <iostream>
using namespace std;
AbstractPhone::AbstractPhone()
{ }
AbstractPhone::~AbstractPhone()
{ }
AbstractPad::AbstractPad()
{
}
AbstractPad::~AbstractPad()
{
}
iPhoneX::iPhoneX()
{
cout<<"iPhoneX..."<<endl;
}
iPhoneX::~iPhoneX()
{
}
iPad::iPad()
{
cout<<"iPad..."<<endl;
}
iPad::~iPad()
{
}
GalaxyNote::GalaxyNote()
{
cout<<"GalaxyNote..."<<endl;
}
GalaxyNote::~GalaxyNote()
{
}
GalaxyTab::GalaxyTab()
{
cout<<"GalaxyTab..."<<endl;
}
GalaxyTab::~GalaxyTab()
{
}
Product.h
分別定義AbstractPhone產品iPhoneX、GalaxyNote和AbstractPad產品iPad、GalaxyTab的類。
程式碼:
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class AbstractPhone
{
public:
virtual ~AbstractPhone();
protected:
AbstractPhone();
private:
};
class AbstractPad
{
public:
virtual ~AbstractPad();
protected:
AbstractPad();
private:
};
class iPhoneX:public AbstractPhone
{
public:
iPhoneX();
~iPhoneX();
protected: private:
};
class iPad:public AbstractPad
{
public:
iPad();
~iPad();
protected: private:
};
class GalaxyNote:public AbstractPhone
{
public:
GalaxyNote();
~GalaxyNote();
protected:
private:
};
class GalaxyTab:public AbstractPad
{
public:
GalaxyTab();
~GalaxyTab();
protected: private:
};
#endif //~_PRODUCT_H_
main.cpp
建立AppleFactory的物件cf1生產cf1->CreatePhone();cf1->CreatePad();
建立SamsungFactory的物件cf2生產cf2->CreatePhone();cf2->CreatePad();
程式碼:
#include "AbstractFactory.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
AbstractFactory* cf1 = new AppleFactory();
cf1->CreatePhone();
cf1->CreatePad();
AbstractFactory* cf2 = new SamsungFactory();
cf2->CreatePhone();
cf2->CreatePad();
return 0;
}
練習二
1.程式執行結果:
2.程式碼分析:
AbstractFactory.cpp
#include "AbstractFactory.h"
#include "Product.h"
#include <iostream>
#include <map>
#include <string>
using namespace std;
//工廠類的實現
//通過類名稱字串獲取類的例項
void* ClassFactory::getClassByName(string className){
map<string, PTRCreateObject>::const_iterator iter;
iter = m_classMap.find(className) ;
if ( iter == m_classMap.end() )
return NULL ;
else
return iter->second() ;
}
//將給定的類名稱字串和對應的建立類物件的函式儲存到map中
void ClassFactory::registClass(string name, PTRCreateObject method){
m_classMap.insert(pair<string, PTRCreateObject>(name, method)) ;
}
//獲取工廠類的單個例項物件
ClassFactory& ClassFactory::getInstance(){
static ClassFactory sLo_factory;
return sLo_factory ;
}
//註冊動作類
class RegisterAction{
public:
RegisterAction(string className,PTRCreateObject ptrCreateFn){
ClassFactory::getInstance().registClass(className,ptrCreateFn);
}
};
//用巨集來替代類重複程式碼。
#define REGISTER(className) \
className* objectCreator##className(){ \
return new className; \
} \
RegisterAction g_creatorRegister##className( \
#className,(PTRCreateObject)objectCreator##className)
AbstractFactory::AbstractFactory()
{
}
AbstractFactory::~AbstractFactory()
{
}
AppleFactory::AppleFactory()
{
}
AppleFactory::~AppleFactory()
{
}
REGISTER(AppleFactory);
AbstractPhone* AppleFactory::CreatePhone()
{
return new iPhoneX();
}
AbstractPad* AppleFactory::CreatePad()
{
return new iPad();
}
SamsungFactory::SamsungFactory()
{
}
SamsungFactory::~SamsungFactory()
{
}
REGISTER(SamsungFactory);
AbstractPhone* SamsungFactory::CreatePhone()
{
return new GalaxyNote();
}
AbstractPad* SamsungFactory::CreatePad()
{
return new GalaxyTab();
}
HuaweiFactory::HuaweiFactory()
{
}
HuaweiFactory::~HuaweiFactory()
{
}
REGISTER(HuaweiFactory);
AbstractPhone* HuaweiFactory::CreatePhone()
{
return new HuaweiPhone();
}
AbstractPad* HuaweiFactory::CreatePad()
{
return new HuaweiPad();
}
AbstractFactory.h
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
#include <map>
#include <iostream>
#include <string>
using namespace std;
typedef void* (*PTRCreateObject)(void);
//工廠類的定義
class ClassFactory{
private:
map<string, PTRCreateObject> m_classMap ;
ClassFactory(){}; //建構函式私有化
public:
void* getClassByName(string className);
void registClass(string name, PTRCreateObject method) ;
static ClassFactory& getInstance() ;
};
class AbstractPhone;
class AbstractPad;
class AbstractFactory
{
public:
virtual ~AbstractFactory();
virtual AbstractPhone* CreatePhone() = 0;
virtual AbstractPad* CreatePad() = 0;
protected:
AbstractFactory();
private:
};
class AppleFactory:public AbstractFactory
{
public:
AppleFactory();
~AppleFactory();
AbstractPhone* CreatePhone();
AbstractPad* CreatePad();
protected:
private:
};
class SamsungFactory:public AbstractFactory
{
public:
SamsungFactory();
~SamsungFactory();
AbstractPhone* CreatePhone();
AbstractPad* CreatePad();
protected:
private:
};
class HuaweiFactory:public AbstractFactory
{
public:
HuaweiFactory();
~HuaweiFactory();
AbstractPhone* CreatePhone();
AbstractPad* CreatePad();
protected:
private:
};
#endif //~_ABSTRACTFACTORY_H_
Product.cpp
#include "Product.h"
#include <iostream>
using namespace std;
AbstractPhone::AbstractPhone()
{ }
AbstractPhone::~AbstractPhone()
{ }
AbstractPad::AbstractPad()
{
}
AbstractPad::~AbstractPad()
{
}
iPhoneX::iPhoneX()
{
cout<<"iPhoneX..."<<endl;
}
iPhoneX::~iPhoneX()
{
}
iPad::iPad()
{
cout<<"iPad..."<<endl;
}
iPad::~iPad()
{
}
GalaxyNote::GalaxyNote()
{
cout<<"GalaxyNote..."<<endl;
}
GalaxyNote::~GalaxyNote()
{
}
GalaxyTab::GalaxyTab()
{
cout<<"GalaxyTab..."<<endl;
}
GalaxyTab::~GalaxyTab()
{
}
HuaweiPhone::HuaweiPhone()
{
cout<<"HuaweiPhone..."<<endl;
}
HuaweiPhone::~HuaweiPhone()
{
}
HuaweiPad::HuaweiPad()
{
cout<<"HuaweiPad..."<<endl;
}
HuaweiPad::~HuaweiPad()
{
}
Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class AbstractPhone
{
public:
virtual ~AbstractPhone();
protected:
AbstractPhone();
private:
};
class AbstractPad
{
public:
virtual ~AbstractPad();
protected:
AbstractPad();
private:
};
class iPhoneX:public AbstractPhone
{
public:
iPhoneX();
~iPhoneX();
protected: private:
};
class iPad:public AbstractPad
{
public:
iPad();
~iPad();
protected: private:
};
class GalaxyNote:public AbstractPhone
{
public:
GalaxyNote();
~GalaxyNote();
protected:
private:
};
class GalaxyTab:public AbstractPad
{
public:
GalaxyTab();
~GalaxyTab();
protected: private:
};
class HuaweiPhone:public AbstractPhone
{
public:
HuaweiPhone();
~HuaweiPhone();
protected:
private:
};
class HuaweiPad:public AbstractPad
{
public:
HuaweiPad();
~HuaweiPad();
protected: private:
};
#endif //~_PRODUCT_H_
main.cpp
#include "AbstractFactory.h"
#include <iostream>
#include<fstream>
using namespace std;
int main(int argc,char* argv[])
{
ifstream infile("in.txt");
string x;
infile>>x;
AppleFactory* ptrObj=(AppleFactory*) ClassFactory::getInstance().getClassByName(x);
ptrObj->CreatePhone();
ptrObj->CreatePad();
infile.close();
return 0;
}
3.具體工廠的類名寫入配置txt檔案中,通過C++的infile輸出。