设计模式:工厂模式

什么是工厂模式

相较于简单工厂,工厂模式最主要的改变在于多了抽象工厂的概念。
为什么要这么做呢?让我们想一下:在简单工厂模式中,如果我们需要新的产品,工厂内部也需要进行改动以附和用户需求,在产品种类繁多的情况下,代码臃肿,耦合程度过高。
工厂模式属于类的创建型模式,关键在于创建产品对象接口,而将实际创建工作发放到子类中,便于分功能开发。工厂模式的核心是一个抽象工厂类,而简单工厂的核心是一个实体类。
在工厂模式里,当系统需要增加产品对象(系列)时,仅仅需要增加这个对象(系列)和对应工厂实体,而不用修改抽象工厂本身,原有的工厂也不需要修改,极大程度上降低了客户端的修改,很好的符合了“开放-封闭”原则。
它有两个突出的优点:

  1. 需求改变时改动量小
  2. 具体创建过程与客户端分离

实现步骤

  1. 提供一个抽象工厂类:我愿意称之为专门建工厂的建筑局,通过它来实例化具体工厂。
  2. 实例化和产品对应的工厂类:即建筑局建工厂。
  3. 提供与产品相关的抽象产品类:工厂买生产原料。
  4. 提供一个或一系列产品:工厂用原料生产产品。

代码与解析

以现实工业为例子,首先有自然界原材料、成立对应的建设局,建设工厂,最后生产产品。因此,在最开始,我们要从抽象产品下手。

//原材料:抽象产品,在这种模式中原材料只有一种类型
class AbsProduct_Mine {	//抽象产品:矿物
public:
	virtual ~AbsProduct_Mine() {};
	AbsProduct_Mine() {
		cout << "挖矿" << endl;
	}
	virtual void produce() = 0;
};

抽象工厂依赖于抽象产品,因为在他的行为中包含了抽象产品,它所知道的是,要生产产品,具体怎么生产,不知道,生产什么产品,不知道,都交给具体工厂来实现,故返回抽象产品类,声明为纯虚函数。

//建设局:抽象工厂类,只存在一个
class AbsFactory {
public:
	virtual ~AbsFactory() {};
	virtual AbsProduct_Mine* createProduct() = 0;
};

具体工厂的建立依赖于产品,如果不知道产品形式,工厂也无从下手,所以先声明具体产品,它由抽象产品得到,比如下面由矿物制造了三个产品,形式上高度统一,实现上可以各有纷纭。

//具体产品,分别由自己的原料生产(继承于自己对应的抽象产品)
class ConProduct_Plane:public AbsProduct_Mine {
public:
	void produce()override {
		cout << "我们用矿物生产了一架飞机" << endl;
}
};

class ConProduct_Tank:public AbsProduct_Mine {
public:
	void produce()override {
		cout << "我们用矿物生产了一辆坦克" << endl;
	}
};

class ConProduct_Computer:public AbsProduct_Mine{
public:
	void produce()override {
		cout << "我们用矿物制造了一台电脑" << endl;
	}
};

最后,产品不能无缘无故产生,需要通过工厂,而工厂需要向建设局请示。
于是具体工厂继承于抽象工厂,一个具体工厂返回一个具体产品,当然,也可以通过类似于简单工厂的传参手法,通过一个接口完成不同产品的生产。

//通过建筑局建工厂,工厂具有生产具体产品功能
//具体工厂继承于抽象工厂,具体工厂重写抽象工厂内置函数完成具体产品类生产
class ConFactory_Plane:public AbsFactory {
public:
	AbsProduct_Mine* createProduct() override{
		return new ConProduct_Plane;
	}
};

class ConFactory_Tank :public AbsFactory {
public:
	AbsProduct_Mine* createProduct() override {
		return new ConProduct_Tank;
	}
};

class ConFactory_Computer :public AbsFactory {
public:
	AbsProduct_Mine* createProduct() override {
		return new ConProduct_Computer;
	}
};

实际上第二种大可不必继承下来,与简单工厂完全一致。

class ConFactory_Mine//:public AbsFactory
{
public:
	static AbsProduct_Mine* createProduct(int arg) {
		switch (arg)//由于case后面是return,不加break也无妨。
		{
		case 1:return new ConProduct_Plane;
		case 2:return new ConProduct_Tank;
		case 3:return new ConProduct_Computer;
		default:return nullptr;
		}
	}
};

调用main函数测试

int main() {
	//子类对象对父类指针初始化,因此还需要添加虚析构函数
	AbsFactory* af = new ConFactory_Plane;
	auto plane = af->createProduct();
	plane->produce();

	af = new ConFactory_Tank;
	auto tank = af->createProduct();
	tank->produce();

	af = new ConFactory_Computer;
	auto com = af->createProduct();
	com->produce();
	cout << "*********************************" << endl;
	ConFactory_Mine::createProduct(1)->produce();
	ConFactory_Mine::createProduct(2)->produce();
	ConFactory_Mine::createProduct(3)->produce();
	return 0;
}

结果如下
在这里插入图片描述
好啦,今天的分享就到这里~

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值