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

02:抽象工廠模式——C++實現

目錄

一、介紹

二、應用場景

三、要點

四、樣例

1、建立抽象產品

2、建立具體產品

3、建立抽象工廠

4、建立具體工廠

5、建立客戶端

五、優缺點


一、介紹

    抽象工廠模式(Abstract Factory Pattern是圍繞一個超級工廠建立其他工廠。該超級工廠又稱為其他工廠的工廠。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。主要解決介面選擇的問題。

    抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品的具體的情況下,建立多個產品族中的產品物件。根據里氏替換原則,任何接受父型別的地方,都應當能夠接受子型別。因此,實際上系統所需要的,僅僅是型別與這些抽象產品角色相同的一些例項,而不是這些抽象產品的例項。換言之,也就是這些抽象產品的具體子類的例項。工廠類負責建立抽象產品的具體子類的例項。

 

二、應用場景

系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。

 

三、要點

將產品歸類分組,然後將好幾組產品構成一族。每個工廠負責生產一族產品,而工廠中的每個方法負責生產一種型別的產品。這樣,客戶端只需要建立具體工廠的例項,然後呼叫工廠物件的工廠方法就可以得到所需要的產品物件。

 

四、樣例

1、建立抽象產品

示例中,需要有兩個產品:自行車和汽車

// product.h	
#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
using namespace std;

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

// 自行車介面
class IBike
{
public:
	virtual string Name() = 0;        // 自行車名稱
};

#endif        // product.h

2、建立具體產品

// concrete_product.h
#ifndef CONCRETE_PRODUCT_H
#define CONCRETE_PRODUCT_H

#include "product.h"

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

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

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

/***** 自行車 *******/
class BenzBike : public IBike
{
public:
	string Name() {
		return "Benz Bike";
	}
};

class BMWBike :public IBike
{
public:
	string Name() {
		return "BMW Bike";
	}
};

class AudiBike :public IBike
{
public:
	string Name() {
		return "BMW Bike";
	}
};

#endif

這樣為自行車和汽車都準備好了具體類。

 

3、建立抽象工廠

產品有了,當然要有相應制造商與其關聯,但在這之前,需要一個抽象工廠:

// factory.h
#ifndef FACTORY_H
#define FACTORY_H

#include "product.h"

// 抽象工廠
class AFactory
{
public:
	enum FACTORY_TYPE {
		BENZ_FACTORY,
		BMW_FACTORY,
		AUDI_FACTORY
	};

	virtual ICar* CreateCar() = 0;        // 生產汽車
	virtual IBike* CreateBike() = 0;        // 生成自行車
	static AFactory* CreateFactory(FACTORY_TYPE factory);        // 建立工廠
};

#endif
// factory.cpp
#include "factory.h"
#include "concrete_factory.h"

// 建立工廠
AFactory* AFactory::CreateFactory(FACTORY_TYPE factory)
{
	AFactory *pFactory = NULL;
	switch (factory)
	{
	case FACTORY_TYPE::BENZ_FACTORY:
		pFactory = new BenzFactory();
		break;
	case FACTORY_TYPE::BMW_FACTORY:
		pFactory = new BMWFactory();
		break;
	case FACTORY_TYPE::AUDI_FACTORY:
		pFactory = new AudiFactory();
		break;
	default:
		break;
	}
	return pFactory;
}

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();
	}

	IBike* CreateBike() {
		return new BenzBike();
	}
};

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

	IBike* CreateBike() {
		return new BMWBike();
	}
};

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

	IBike* CreateBike() {
		return new AudiBike();
	}
};

#endif

這樣具體的產品就與其製造商聯絡起來了。

 

5、建立客戶端

// main.cpp
#include "factory.h"
#include "product.h"
#include <iostream>

using namespace std;

#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){ delete(p); (p) = NULL; } }
#endif

int main()
{
	// Benz
	AFactory *pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::BENZ_FACTORY);
	ICar *pCar = pFactory->CreateCar();
	IBike *pBike = pFactory->CreateBike();

	cout << "Benz factory - Car: " << pCar->Name() << endl;
	cout << "Benz factory - Bike: " << pBike->Name() << endl;
	SAFE_DELETE(pCar);
	SAFE_DELETE(pBike);
	SAFE_DELETE(pFactory);

	// BMW
	pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::BMW_FACTORY);
	ICar *pCar = pFactory->CreateCar();
	IBike *pBike = pFactory->CreateBike();

	cout << "BMW factory - Car: " << pCar->Name() << endl;
	cout << "BMW factory - Bike: " << pBike->Name() << endl;
	SAFE_DELETE(pCar);
	SAFE_DELETE(pBike);
	SAFE_DELETE(pFactory);

	// Audi
	pFactory = AFactory::CreateFactory(AFactory::FACTORY_TYPE::AUDI_FACTORY);
	ICar *pCar = pFactory->CreateCar();
	IBike *pBike = pFactory->CreateBike();

	cout << "Audi factory - Car: " << pCar->Name() << endl;
	cout << "Audi factory - Bike: " << pBike->Name() << endl;
	SAFE_DELETE(pCar);
	SAFE_DELETE(pBike);
	SAFE_DELETE(pFactory);

	getchar();
	return 0;
}

輸出結果:

Benz factory - Car: Benz Car
Benz factory - Bike : Benz Bike
Bmw factory - Car : Bmw Car
Bmw factory - Bike : Bmw Bike
Audi factory - Car : Audi Car
Audi factory - Bike : Audi Bike

 

五、優缺點

優點:

可以支援不同型別的產品,使得模式靈活性更強。

當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。

缺點:

不便於產品族擴充套件。