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

 

五、优缺点

优点:

可以支持不同类型的产品,使得模式灵活性更强。

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点:

不便于产品族扩展。

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幻欢子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值