工廠方法,跟抽象工廠、建造者模式等解決的問題都類似,通過將產品和其實現分離,達到了客戶和具體產品之間的解耦。 工廠方法,其精髓就是他名字本身,在工廠類中提供一個工廠方法,該方法返回具體的產品。客戶只需要關注該產品的接口(一般是抽象父類),而無需關注起具體實現和創建過程。 工廠方法的一個缺點是客戶可能僅僅為了穿件一個具體的產品,需要增加creator的一個子類。一般通過c++的模板方法可以解決這個問題。 下面是一個簡單的例子,還是生產pc和pad的一個工廠。
/**
* @file test_factory_method.cpp
* @author itegel
* @date 2013/09/16 10:50:40
* @brief 還是生產電腦的問題
*
**/
#include <iostream>
#include <string>
using namespace std;
//product
class Computer{
public:
Computer(){}
~Computer(){}
virtual void WhoIam(){
cout<<"Computer!"<<endl;
}
virtual void Compute(string expr){
cout<<"computing "<<expr<<"..."<<endl;
}
virtual void Display(string content){
cout<<"Display: "<<content<<endl;
}
};
class PC: public Computer{
public:
PC(){}
~PC(){}
virtual void WhoIam(){
cout<<"PC!"<<endl;
}
virtual void Compute(string expr){
cout<<"PC computing "<<expr<<"... used 0.0000001ms"<<endl;
}
};
class IPad: public Computer{
public:
IPad(){}
~IPad(){}
virtual void WhoIam(){
cout<<"IPad!"<<endl;
}
virtual void Compute(string expr){
cout<<"IPad conputing "<<expr<<"... used 0.001ms"<<endl;
}
} ;
//factory, so simple, no extention is implemented
template <class T>
class Creator{
public:
Creator(){}
~Creator(){}
//factory method
virtual T * CreateComputer(){
return new T();
}
};
//client
int main(){
Computer * computer = NULL;
//PC
cout<<"start produce pc and do some job!"<<endl;
Creator<PC> *creator = new Creator<PC>();
computer = creator->CreateComputer();
computer->WhoIam();
computer->Compute("1+1=");
computer->Display("2");
delete creator;
delete computer;
//IPad
cout<<endl<<"start produce IPad and do some job!"<<endl;
Creator<IPad> *creator2 = new Creator<IPad>();
computer = creator2->CreateComputer();
computer->WhoIam();
computer->Compute("1+1=");
computer->Display("2");
delete computer;
return 0;
}
運行結果如下:
start produce pc and do some job! PC! PC computing 1+1=... used 0.0000001ms Display: 2 start produce IPad and do some job! IPad! IPad conputing 1+1=... used 0.001ms Display: 2
從效果看,工廠方法的引入,使得產品的具體創建過程對客戶封閉,而對於具體產品的擴展卻是開放的。用戶想增加一個產品,只需要從product抽象類繼承一個子類出來,並實現其接口即可。 抽象工廠,抽象方法和構造器都是創建型模型中使用非常多的,也是面向對象設計中最基本的幾種模式。要解決的問題均相似,只是在應用場景上稍有差別。很多時候這幾個還交叉使用。比如抽象工廠中,也可以通過工廠方法或建造者,獲取具體產品。而建造者只是更關注產品的組裝過程,產品的單個部分的創建也可以使用其他模式生成。