- 1 概述
- 2 圖解
- 3 優缺點
- 4 應用場景
- 5 執行個體
- 1 producth
- 2 factoryh
- 3 maincpp
1、 概述
工廠方法(Factory Method)模式,也叫虛拟構造器(Virtual Constructor)模式或者多态工廠(Polymorphic Factory)模式,它屬于類建立型模式。 在工廠方法模式中,工廠父類負責定義建立産品對象的公共接口,而子類負責生成具體産品對象,這樣做的目的是将産品類的執行個體化延遲到工廠子類中完成,即通過工廠子類來确定究竟應該執行個體化哪一個具體産品類。
2、 圖解
現在有A、B、C三種産品,相對應的有三個工廠:工廠A負責生産A産品,工廠B負責生産B産品,工廠C負責生産C産品。這時候客戶不需要告訴工廠生産哪種産品了,隻需要告訴對應的工廠生産就可以了。
工廠方法模式包含如下角色:
- Factory 抽象工廠角色:
是工廠方法模式的核心,與應用程式無關。任何在模式中建立的對象的工廠類必須實作這個接口。
- ConcreteFactory 具體工廠角色(圖中的FactoryA、FactoryB、FactoryC)
實作抽象工廠接口的具體工廠類,被應用程式調用以建立産品對象。
- Product 抽象産品角色:
抽象産品角色是所建立所有對象的父類,負責描述所有執行個體的公共接口。
- ConcreteProduct 具體産品角色(圖中的ProductA、ProductB、ProductC):
實作了抽象産品角色所定義的接口 ,由專門的具體工廠角色建立。
3、 優缺點
優點:
- 子類提供挂鈎。基類為工廠方法提供預設實作,子類可以重寫新的實作,也可以繼承父類的實作。– 加一層間接性,增加了靈活性
- 屏蔽産品類。産品類的實作如何變化,調用者都不需要關心,隻需關心産品的接口,隻要接口保持不變,系統中的上層子產品就不會發生變化。
- 典型的解耦架構。高層子產品隻需要知道産品的抽象類,其他的實作類都不需要關心,符合迪米特法則,符合依賴倒置原則,符合裡氏替換原則。
- 多态性:客戶代碼可以做到與特定應用無關,适用于任何實體類。
缺點:
- 添加新産品時,需要編寫新的具體産品類 ,而且還要提供與之對應的具體工廠類,系統中類的将成對增加,在一定程度上增加了系統的複雜度。
- 由于考慮到系統的可擴充性,需要引入抽象層,在用戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和了解難度,且在實作時可能需要用到DOM、反射等技術,增加了系統的實作難度。
4、 應用場景
如果一個對象擁有很多子類,那麼建立該對象的子類使用工廠模式是最合适的,不但可以面向接口的程式設計,為維護以及開發帶來友善。
如果建立某個對象時需要進行許多額外的操作,如查詢資料庫然後将查詢到的值賦予要建立的對象(單例初始化時使用比較多),或是需要許多額外的指派等等。如果檢視JDK源碼中,會發現許多成員變量在對象構造時,通過工廠方法進行建立的。因為這些成員變量本身的建立也很複雜。不可能建立對象時,在該對象的構造方法裡建立成員變量然後再指派給該成員變量。而且使用工廠模式也提高了代碼的重用性。
5、 執行個體
5.1 product.h
#ifndef PRODUCT_H
#define PRODUCT_H
#include <iostream>
// 産品基類
class Product
{
public:
Product() {}
virtual ~Product(){}
virtual void detail() const
{
std::cout << "This is the base class of product." << std::endl;
}
};
// 産品A
class ProductA : public Product
{
public:
ProductA() {}
~ProductA() {}
virtual void detail() const
{
std::cout << "This is ProductA." << std::endl;
}
};
// 産品B
class ProductB : public Product
{
public:
ProductB() {}
~ProductB() {}
virtual void detail() const
{
std::cout << "This is ProductB." << std::endl;
}
};
// 産品C
class ProductC : public Product
{
public:
ProductC() {}
~ProductC() {}
virtual void detail() const
{
std::cout << "This is ProductC." << std::endl;
}
};
#endif // PRODUCT_H
5.2 factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "product.h"
// 工廠基類
class Factory
{
public:
Factory(){}
virtual ~Factory(){}
static Product* produce()
{
return NULL;
}
};
// 工廠A
class FactoryA : public Factory
{
public:
FactoryA();
virtual ~FactoryA();
static Product* produce()
{
return new ProductA();
}
};
// 工廠B
class FactoryB : public Factory
{
public:
FactoryB();
virtual ~FactoryB();
static Product* produce()
{
return new ProductB();
}
};
// 工廠C
class FactoryC : public Factory
{
public:
FactoryC();
virtual ~FactoryC();
static Product* produce()
{
return new ProductC();
}
};
#endif // FACTORY_H
5.3 main.cpp
#include <iostream>
#include "factory.h"
using namespace std;
int main()
{
Product* productA = NULL;
productA = FactoryA::produce();
productA->detail();
cout << "==============" << endl;
Product* productB = NULL;
productB = FactoryB::produce();
productB->detail();
cout << "==============" << endl;
Product* productC = NULL;
productC = FactoryC::produce();
productC->detail();
cout << "==============" << endl;
delete productA;
delete productB;
delete productC;
return ;
}
運作結果