1. 程式人生 > >04:工廠模式——C++實現

04:工廠模式——C++實現

目錄

一、簡介

二、應用場景

三、要點

四、樣例

五、優缺點


一、簡介

工廠模式(Factory Pattern:定義一個建立物件的介面,讓其子類自己決定例項化哪一個工廠類,工廠模式使其建立過程延遲到子類進行。主要解決介面選擇的問題。此模式的核心思想是封裝類中不變的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、複用以及方便後期維護拓展的目的。“工廠方法模式”是“簡單工廠模式”的進一步抽象和推廣。工廠模式基本和簡單工廠模式差不多,簡單工廠模式 - 在產品子類新增時,需要新增一個判斷分支,這違背了開放-封閉原則。因此,工廠模式就是為了解決這個問題而產生的。

 

二、應用場景

當我們明確地計劃不同條件下建立不同例項時。如:

1、日誌記錄器:記錄可能記錄到本地硬碟、系統事件、遠端伺服器等,使用者可以選擇記錄日誌到什麼地方。

2、資料庫訪問,當用戶不知道最後系統採用哪一類資料庫,以及資料庫可能有變化時。

3、設計一個連線伺服器的框架,需要三個協議,"POP3"、"IMAP"、"HTTP",可以把這三個作為產品類,共同實現一個介面。

 

三、要點

作為一種建立類模式,在任何需要生成複雜物件的地方,都可以使用工廠方法模式。有一點需要注意的地方就是複雜物件適合使用工廠模式,而簡單物件,特別是只需要通過 new 就可以完成建立的物件,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統的複雜度。

 

四、樣例

Factory(抽象工廠):是工廠方法模式的核心,與應用程式無關。任何在模式中建立的物件的工廠類必須實現這個介面。

ConcreteFactory(具體工廠):實現抽象工廠介面的具體工廠類,包含與應用程式密切相關的邏輯,並且被應用程式呼叫以建立產品物件。

Product(抽象產品):所建立物件的基類,也就是具體產品的共同父類或共同擁有的介面。

ConcreteProduct(具體產品):實現了抽象產品角色所定義的介面。某具體產品有專門的具體工廠建立,它們之間往往一一對應。

 

1、建立抽象產品

// product.h
#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
using namespace std;

// 汽車介面
class ICar
{
public:
	virtual string Name() = 0;        // 汽車名稱
};

#endif

2、建立具體產品

// concrete_product.h
#ifndef CONCRETE_PRODUCT_H
#define CONCRETE_PRODUCT_H

#include "product.h"

class BenzCar :public ICar
{
public:
	string Name() {
		return "Benz Car";
	}
};

class BMWCar :public ICar
{
public:
	string Name() {
		return "BMW Car";
	}
};

class AudiCar :public ICar
{
public:
	string Name() {
		return "Audi Car";
	}
};

#endif

3、建立抽象工廠

// factory.h
#ifndef FACTORY_H
#define FACTORY_H

#include "product.h"

// 工廠介面
class AFactory
{
public:
	virtual ICar* CreateCar() = 0;        // 生成汽車

};

#endif

4、建立具體工廠

// concrete_factory.h
#ifndef CONCRETE_FACTORY_H
#define CONCRETE_FACTORY_H

#include "factory.h"
#include "concrete_product.h"

class BenzFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new BenzCar();
	}
};

class BMWFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new BMWCar();
	}
};

class AudiFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new AudiCar();
	}
};

#endif

5、客戶端程式

// concrete_factory.h
#ifndef CONCRETE_FACTORY_H
#define CONCRETE_FACTORY_H

#include "factory.h"
#include "concrete_product.h"

class BenzFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new BenzCar();
	}
};

class BMWFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new BMWCar();
	}
};

class AudiFactory :public AFactory
{
public:
	ICar* CreateCar() {
		return new AudiCar();
	}
};

#endif

6、輸出:

Benz factory : Benz Car
Bmw factory : Bmw Car
Audi factory : Audi Car

五、優缺點

優點:

1、一個呼叫者想建立一個物件,只要知道其名稱就可以了。

2、擴充套件性高,如果想增加一個產品,只要擴充套件一個工廠類就可以。

3、遮蔽產品的具體實現,呼叫者只關心產品的介面。

 

缺點:

每次增加一個產品時,都需要增加一個具體類和物件實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事。