C++設計模式~工廠模式(Factory)
阿新 • • 發佈:2018-12-20
問題:
在面向物件系統設計中經常可以遇到以下的兩類問題:
問題1
為了提高內聚(Cohesion) 和鬆耦合(Coupling),需要我們抽象出一些類的公共介面以形成抽象基類或者介面。這樣我們可以通過宣告一個基類的指標指向子類物件進而達到多型的目的,但是這樣很容易出現一個問題:n多的子類繼承自抽象基類,我們不得不在每次要用到子類的地方就編寫new xxx();這樣就有兩個問題產生:
- 必須要有實際子類的名稱(命名困難,可讀性和可記憶性都不友好)
- 程式的擴充套件性和維護變得困難
問題2
還有一種情況就是在父類中並不知道具體要例項化哪一個具體的子類。意思是:假如類B是一個抽象父類,A是一個類,現在我們在類 A 中要使用到類 B,但是在 A 中並不知道具體要例項化哪一個 B 的子類,但是在類 A 的子類 D 中是可以知道的,在 A 中我們沒有辦法直接使用類似於 new xxx()的語句,因為根本就不知道xxx是什麼。
以上兩個問題也就引出了 Factory 模式的兩個最重要的功能:
- 定義建立物件的介面,封裝了物件的建立;
- 使得具體化類的工作延遲到了子類中。
模式選擇:
- 在第一個問題中,我們經常就是宣告一個建立物件的介面,並封裝了物件的建立過程。Factory 這裡類似於一個真正意義上的工廠(生產物件)。
- 在第二個問題中,我們需要提供一個物件建立物件的介面,並在子類中提供其具體實現(因為只有在子類中可以決定到底例項化哪一個類)。
Factory 的結構示意圖1
圖 1 所以的 Factory 模式經常在系統開發中用到,但是這並不是 Factory 模式的最大威力所在(因為這可以通過其他方式解決這個問題)。Factory 模式不單是提供了建立物件的介面,其最重要的是延遲了子類的例項化(第二個問題),以下是這種情況的一個Factory 的結構示意圖:
Factory 模式結構示意圖 2
圖 2 中關鍵中 Factory 模式的應用並不是只是為了封裝物件的建立,而是要把物件的建立放到子類中實現,Factory 中只是提供了物件建立的介面,其實現將放在 Factory 的子類ConcreteFactory 中進行。這是圖 2 和圖 1 的區別所在。
實現
Product.h
#ifndef PRODUCT_H #define PRODUCT_H class Product { public: virtual ~Product() = 0; protected: Product(); }; class ConcreteProduct:public Product { public: ~ConcreteProduct(); ConcreteProduct(); }; #endif // PRODUCT_H
Product.cpp
#include "product.h"
#include <iostream>
using namespace std;
Product::Product()
{
cout<<"CreateProduct"<<endl;
}
Product::~Product()
{
cout<<"DestoryProduct"<<endl;
}
ConcreteProduct::ConcreteProduct()
{
cout<<"ConcreteProduct...."<<endl;
}
ConcreteProduct::~ConcreteProduct()
{
cout<<"~ConcreteProduct...."<<endl;
}
factory.h
#ifndef FACTORY_H
#define FACTORY_H
class Product;
class Factory
{
protected:
Factory();
public:
virtual ~Factory() = 0;
virtual Product *CreateProduct() = 0;
};
class ConcreteFactory:public Factory
{
public:
~ConcreteFactory();
ConcreteFactory();
Product *CreateProduct();
};
#endif // FACTORY_H
factory.cpp
#include "factory.h"
#include "product.h"
#include <iostream>
using namespace std;
Factory::Factory()
{
cout<<"CreatedFactory..."<<endl;
}
Factory::~Factory()
{
cout<<"DestoryFactory..."<<endl;
}
ConcreteFactory::ConcreteFactory()
{
cout<<"ConcreteFactory..."<<endl;
}
ConcreteFactory::~ConcreteFactory()
{
cout<<"~ConcreteFactory..."<<endl;
}
Product *ConcreteFactory::CreateProduct()
{
return new ConcreteProduct();
}
main.cpp
#include <iostream>
#include "product.h"
#include "factory.h"
using namespace std;
void test()
{
Factory *fac = new ConcreteFactory();
Product *p = fac->CreateProduct();
delete fac;
delete p;
}
int main()
{
test();
return 0;
}