简单工厂,工厂方法,抽象工厂模式

简单工厂模式

简单工厂模式(Simple Factory Pattern)专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。

简单工厂模式,是一种实例化对象的方式,只要输入需要实例化对象的名字,就可以通过工厂对象的相应工厂函数来制造你需要的对象。

简单工厂模式的角色

(1)Factory工厂角色(工厂类):

工厂角色即工厂类,是简单工厂模式的核心,负责创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需要的产品对象。

(2)Product(抽象产品角色):

抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公告接口。所创建的具体产品对象都是其子类对象。

(3)ConcreteProduct(具体产品角色):

具体产品角色是简单工厂模式的创建目标。每个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的方法。

简单工厂的介绍

简单工厂(Simple Factory)不属于标准的OOP设计模式中的一项,在编写大型C++软件的时候,代码里面会出现很多的类,每次创建对象的时候,都需要通过new 类名称的方式来生成对象,这样一来,用户需要记忆很多类的名称,暂且不管记不记得住,这样的设计使得代码很难维护,类名如果做了改变,那么所有使用类名称的地方都需要去修改,耦合性太强,不符合我们软件设计的思想,Simple Factory就是在这样的需求下诞生的。

在这里插入图片描述

我们把对象的创建全部都封装在了SimpleFactory的create方法中,在这里我们传入一个Product就可以创建一个对象,省略了new的过程

#include <iostream>
#include <string>
using namespace std;
//产品类型的声明,抽象产品
class  Product
{
public:
	Product(string name) : ProductName(name) {};
	virtual void show() = 0;
protected:
	string ProductName;
};

//具体产品的声明
class BaoMa :public Product
{
public:
	BaoMa(string name) : Product(name) {};
	void show()
	{
		std::cout << "This is BaoMa Product" << char(10);
		std::cout << ProductName << char(10);
	}
};


//具体产品2 的申明
class BengChi :public Product
{
public:
	BengChi(string name) : Product(name) {};
	void show()
	{
		std::cout << "This is <BengChi> Product" << char(10);
		std::cout << ProductName << char(10);
	}
};

enum ProductType
{
	 BWM,
	 BC
};

class SimpleFactory
{
public:
	//通过传入的枚举类型,创建对应的对象,返回对象的基类指针
	Product* createProduct(ProductType type)
	{
		switch (type)
		{
		case BWM:
			return new BaoMa("宝马");
			break;
		case BC:
			return new BengChi("奔驰");
			break;
		default:
			std::cout << "你输入了错误的名字" << type << char(10);
			break;
		}
	}
};


int main()
{
	//创建简单工厂的实例
	SimpleFactory sf;
	unique_ptr<Product> p1(sf.createProduct(BWM));
	unique_ptr<Product> p2(sf.createProduct(BC));


	p1->show();
	p2->show();

	return 0;
}

工厂方法

UML图片

在这里插入图片描述

通过产生具体的工厂创建具体的产品,做到了在扩充新产品时,能够达到软件设计的“开-闭”原则

代码

#include <iostream>
#include <string>
using namespace std;

class AbstractProduct
{
public:
	AbstractProduct(string name): _name(name){}
	//模拟产品对象的抽象方法
	virtual void show() = 0;
protected:
	string _name;
};

class ProductA:public AbstractProduct
{
public:
	//其实这是一个委托构造函数
	ProductA(string name) : AbstractProduct(name) {}
	void show() 
	{ 
		std::cout << "这是一个产品A的对象"; char(10);
		std::cout << "string name : " << _name << char(10);
	}
};

class ProductB :public AbstractProduct
{
public:
	//其实这是一个委托构造函数
	ProductB(string name) : AbstractProduct(name) {}
	void show() { 
		std::cout << "这是一个产品B的对象"<< char(10);
		std::cout << "string name : " << _name << char(10);
	}
};

//定义枚举类型的数据
enum  ProductType
{
	XIAOMI,
	HUAWEI,
};

//定义抽象工厂
class AbstractFactory
{
public:
	virtual AbstractProduct* createProduct() = 0;
};

//小米手机工厂
class XiaoMiFactory:public AbstractFactory
{
public:
	AbstractProduct* createProduct()
	{
		std::cout << "调用了小米工厂的创建方法" << char(10);
		return new ProductA("小米手机");
	}
};

//华为手机工厂
class HuaWeiFactory :public AbstractFactory
{
public:
	AbstractProduct* createProduct()
	{
		std::cout << "调用了华为工厂的创建方法" << char(10);
		return new ProductB("华为手机");
	}
};

int main()
{
	//在这里我们使用智能指针,创建具体工厂
	unique_ptr<AbstractFactory> Fac1(new XiaoMiFactory);
	unique_ptr<AbstractFactory> Fac2(new HuaWeiFactory);

	//通过工厂方法创建产品
	unique_ptr<AbstractProduct> Pro1(Fac1->createProduct());
	unique_ptr<AbstractProduct> Pro2(Fac2->createProduct());

	Pro1->show();
	Pro2->show();

	return 0;
}

工厂方法可以解决一簇产品(一款产品有多种形态)的问题,并且工厂一次只能生产一种产品;但需要一个工厂能够同时生产多款产品时,则需要用到抽象工厂模式

工厂方法总结:

仔细理解上面的工厂方法模式,会发现一个问题,就是每一个实例工厂负责生产一个实例产品,也就是一个产品对应一个工厂,一个工厂对应一个产品,那么小米不仅仅生产手机,还生产耳机,智能手环,智能插座等等相关的小米产品簇,不可能给这每一个产品都创建一个工厂类,那样的话代码中的类就太多了,不好维护,而且也不符合实际情况。

实际上小米或者华为的工厂里面,有相关联的产品簇都是在一个工厂完成创建的;BMW或者Audi汽车制造工厂除了生产汽车,生产线上也有可能生产轮胎,或者其它的汽车附属产品。

所以对于包含产品簇这么一类实体关系的设计,就需要使用Abstract Factory抽象工厂了,你也可以把上面的工厂方法看作只生产一种产品的抽象工厂,本质是相同的。

抽象工厂

在这里插入图片描述

可以看到,抽象工厂模式把一个产品簇的产品放在一个工厂类中去创建,不仅大大减少了工厂类的个数,更符合现实中工厂生产产品的模式。根据上面的内容描述,仔细思考简单工厂,工厂方法和抽象工厂的区别联系

代码实现

#include <iostream>
using namespace std;

//抽象产品 手机类
class AbstractPhone
{
public:
	AbstractPhone(string name) : _name(name) {};
	//模拟产品对象的一个抽象的方法
	virtual void show() = 0; 
protected:
	string _name;
};

//产品实体类型 小米
class XiaoMiPhone: public AbstractPhone
{
public:
	XiaoMiPhone(string name) : AbstractPhone(name) {};
	void show()
	{
		std::cout << "这是" << _name << "手机" << char(10);
	}
};

//产品实体类型 华为
class HuaweiPhone : public AbstractPhone
{
public:
	HuaweiPhone(string name) : AbstractPhone(name) {};
	void show()
	{
		std::cout << "这是" << _name << "手机" << char(10);
	}
};

//抽象产品 手环
class AbstractCircle
{
public:
	AbstractCircle(string name) : _name(name) {};
	//模拟产品对象的一个抽象的方法
	virtual void show() = 0;
protected:
	string _name;
};

//产品实体 小米手环
class  XiaoMiCircle:public AbstractCircle
{
public:
	XiaoMiCircle(string name) :AbstractCircle(name) {};
	void show()
	{
		std::cout << "这是" << _name << "手环" << char(10);
	}
};

//产品实体 华为手环
class  HuaWeiCircle :public AbstractCircle
{
public:
	HuaWeiCircle(string name) :AbstractCircle(name) {};
	void show()
	{
		std::cout << "这是" << _name << "手环" << char(10);
	}
};

//抽象工厂,创建一个产品族的设备的产品
class AbstractFactory
{
public:
	//创建手机的纯虚函数
	virtual AbstractPhone* createPhone() = 0;
	virtual AbstractCircle* createCircle() = 0;
};

//生产小米的工厂
class XiaoMiFactory:public AbstractFactory
{
public:
	virtual AbstractPhone* createPhone()
	{
		return new XiaoMiPhone("小米14Pro");
	}
	virtual AbstractCircle* createCircle()
	{
		return new XiaoMiCircle("小米手环NFC版本");
	}
};

//生产华为的工厂
class HuaWeiFactory :public AbstractFactory
{
public:
	virtual AbstractPhone* createPhone()
	{
		return new XiaoMiPhone("华为Mate60 pro");
	}
	virtual AbstractCircle* createCircle()
	{
		return new XiaoMiCircle("华为GT Runing");
	}
};



int main()
{
	//利用智能指针,创建生产的工厂
	unique_ptr< AbstractFactory> fac1(new XiaoMiFactory);
	unique_ptr< AbstractFactory> fac2(new HuaWeiFactory);

	//通过工厂来生产手机的
	unique_ptr< AbstractPhone > phone1(fac1->createPhone());
	unique_ptr< AbstractPhone > phone2(fac2->createPhone());
	phone1->show();
	phone2->show();

	//生产手环
	unique_ptr< AbstractCircle > cir1(fac1->createCircle());
	unique_ptr< AbstractCircle > cir2(fac2->createCircle());
	cir1->show();
	cir2->show();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_73202575/article/details/135367879
今日推荐