c++工厂模式

一、什么是工厂模式

将一个复杂的对象的构建和其部件分离,将耦合度降到最低。换句话说,就是当初始化一个对象需要很多步骤、复杂工作时,不要使用new来创建对象,而是通过工厂模式抽象出来专门生成对象的一种方法。代码量会增加,但耦合度降低、维护方便。

二、代码结构实现工厂模式

工厂模式设计思路:工厂类负责对产品类的创建,即产品类不能直接实例,不能new,产品类的对象必须由工厂类创建。基于这个原则,产品类可抽象出来,可实现几个子类,针对不同情况,工厂类分别可以创建不同的产品实例(多种产品子类),这些子类,外部同样不能直接new出来,必须由工厂类创建。
2.1、产品类的代码结构

class Product
{
public:
	virtual~Product()=0;
	virtual void someFunction()=0;
protected:
	Product();
private:

};

class ConcreteProduct :public Product
{
public:
	~ConcreteProduct();
	void someFunction() 
	{
		//具体实现某些功能
	};
private:
	ConcreteProduct();
};

Product为抽象产品,具有某些共同属性的方法,具体实现过程,让子类实现。由于产品类不可直接new创建,所以需要将构造函数私有化,外部不可访问。(那么工厂类如何可以访问呢?稍后讲解)
2.2、工厂类的代码结构

class Product;
class ConcreteProduct;
class Factory
{
public:
    // 用于创建产品类
	Product* CreateProduct()
	{
	 Product*product=new ConcreteProduct;
	 return product;
	}
};

Factory为工厂类,用于创建具体产品类对象,如 Product*product=new ConcreteProduct;但是,此时的工厂类是无法访问到子产品类的构造函数的(已经保护起来了),那么此时需要一个友元操作,让子产品类的所有私有的属性、方法,都能够让工厂类访问,此时就需要在子产品类添加友元:friend class Factory;
即最后子产品类,长这样的

class ConcreteProduct :public Product
{
public:
	~ConcreteProduct();
	void someFunction() 
	{
		//具体实现某些功能
	};
	friend class Factory;
private:
	ConcreteProduct();
};

工厂模式的代码结构就完成了

三、代码实现的注意事项

在编写工厂方法有几个需要注意的地方:
1、抽象产品和子产品类都需要私有化构造函数,否则外部能new出来,工厂模式就失效
2、子产品类需要添加工厂的友元声明,否则工厂类无法访问构造函数,就无法创建对象
3、工厂类需要一个创建产品类的方法,创造子产品类(因为抽象产品为抽象类,此时通过子类对象传递指针,当具体使用这个指针时,实质是子类的指针,执行子类的函数)
4、这点最容易忽略:抽象产品类的析构函数必须为纯虚函数,子类释放时,根据这个纯虚函数指针释放内存,否则会造成内存泄漏,具体关于纯虚函数指针方面以后在讨论。

四、工厂模式的使用方法

现在可以使用工厂来创建产品子类了

Factory factory;
Product* p=factory.CreateProduct();// 注意此时返回的是子类的指针
p->someFunction();// 调用的是子产品类的someFunction成员函数,这个过程就是动态绑定的过程,也是c++的继承与多态特性

在使用过程中可以发现,子产品类并不能new创建,只能通过工厂类创建,这就是工厂模式的核心。
在实际运用过程中会经常遇到这样的方式,此处简单用一个例子演示:
一个汽车公司可以生产三款汽车,如奥迪、宝马、日产,这些汽车各自有自身的功能如不同的速度,还有其他各方面的细节,省略。简单的把这个工厂模式实现一下。
1、产品类的编写

class ICar
{
public:
	virtual ~ICar() = 0;
	virtual void Speed() = 0;
private:
	ICar();
};

class AoDi :public ICar
{
public:
	void Speed()
	{
		// 各自的速度
	};
private:
	AoDi();
	friend class CarFactory;
};

class BaoMa :public ICar
{
public:
	void Speed()
	{
		// 各自的速度
	};
private:
	BaoMa();
	friend class CarFactory;
};
class RiChan :public ICar
{
public:
	void Speed()
	{
		// 各自的速度
	};
private:
	RiChan();
	friend class CarFactory;
};

2、工厂类的编写

class CarFactory
{
public:
	enum CarStyle
	{
		AODI,BAOMA,RICHAN
	};
	ICar* CreateCar(CarStyle style)
	{
		ICar*car = nullptr;
		switch (style)
		{
		case CarFactory::AODI:
			car = new AoDi;
			break;
		case CarFactory::BAOMA:
			car = new BaoMa;
			break;
		case CarFactory::RICHAN:
			car = new RiChan;
			break;
		}
		return car;
	}
private:
};

使用编写好的工厂模式:

CarFactory fac;
ICar* baoma = fac.CreateCar(CarFactory::BAOMA);// 创建一台宝马
ICar* aodi = fac.CreateCar(CarFactory::AODI);// 创建一台奥迪
ICar* richan = fac.CreateCar(CarFactory::RICHAN);// 创建一台日产
baoma->Speed();
aodi->Speed();
richan->Speed();

五、优缺点

1、优点:用户根据自己需求创建不同的子类,模块化清晰,各司其职,分工明确
2、缺点:每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值