【C++】设计模式之——工厂设计模式的原理与实现

工厂设计模式

工厂设计模式提供了生成对象的最佳方法,这一设计模式的优势就在于屏蔽了生成对象复杂的过程。有三种工厂模式,分别为:

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

简单工厂模式

原理:工厂生产产品,而这里的产品指的就是对象。在简单工厂模式中,用一个标识对应一个对象的方法,要生成某一产品时,只需要传入对应的标识,这样做的优势是当需要生产大量的对象时,不需要对对象名进行记忆,并且屏蔽了生产对象的复杂过程。

特点:所有对象在一个工厂生产

代码:

#include<iostream>
#include<string>

class Fruit//构造一个抽象类,水果的类
{
public:
	Fruit(std::string name):mname(name){}
	virtual void operation() = 0;
	virtual ~Fruit(){};//加virtual使用虚析构;当基类的指针指向派生类的对象,派生类对象调用析构时,为了使派生类对象成功释放空间。
protected:
	std::string mname;
};
class Apple :public Fruit//一个apple的类继承水果的类
{
public:
	Apple(std::string name):Fruit(name){}//指定基类的构造方法
	void operation()
	{
		std::cout<<"this is a "<< mname <<std::endl;
	}
};
class Orange :public Fruit//一个orange的类继承水果的类
{
public:
	Orange(std::string name) :Fruit(name){}//指定基类的构造方法
	void operation()
	{
		std::cout << "this is a " << mname << std::endl;
	}
};
class Factory//工厂的类,生产对象
{
public:
	Fruit* createProduct(int flag)//返回的是一个对象,而这些对象都有的一个特点是继承水果这个类,所以返回值用基类的指针
	{
		switch(flag)
		{
		case 1:
			return new Apple("apple");
			break;
		case 2:
			return new Orange("orange");
			break;
		default:
			break;
		}
	}
};
int main()
{
	Factory *p = new Factory();
	Fruit *pl = p->createProduct(1);
	pl->operation();
}

运行结果:

简单工厂模式的缺点 :当需要再创建一个banana时,需要在Factory类中的switch增加一个选择分支语句。这样就违背了C++五大原则之一:开放-封闭原则,开放的意思是新的版本中可以使用旧的版本,封闭的意思是新的版本不可以修改旧的版本的内容;显然,要添加一个对象时,必然会修改Factory这个类。

适于场景:由于添加对象会违背开放-封闭原则,所以简单工厂模式适用于规模固定的场景下

工厂方法模式

原理:工厂方法模式就是为了解决简单工厂模式存在的缺陷,简单工厂模式时一个工厂生产多个对象,所以在一个工厂中添加对象,会对Fatory这个类进行修改,怎么样才能对Factory不进行修改呢?这里就使用了一个工厂只生产一个对象的方法。因为一个工厂生成一个对象,就不需要标识符标识对应的对象。

特点:一个工厂生成一个对象

代码:

#include<iostream>
#include<string>
class Product//产品的抽象类
{
public:
	Product(std::string name):mname(name){}
	virtual ~Product(){}//加virtual使用虚析构;当基类的指针指向派生类的对象,派生类对象调用析构时,为了使派生类对象成功释放空间。
	virtual void operation() = 0;
protected:
	std::string mname;
};
class ProductA:public Product
{
public:
	ProductA(std::string name):Product(name){}//指定基类的构造方法
	void operation()
	{
		std::cout << "this is a "<<mname<<std::endl;
	}
};
class ProductB:public Product
{
	public:
	ProductB(std::string name):Product(name){}//指定基类的构造方法
	void operation()
	{
		std::cout << "this is a "<<mname<<std::endl;
	}
};
class Factory//工厂的抽象类
{
public:
	Factory(std::string name):mname(name){}
	virtual ~Factory(){}
	virtual Product* createProduct() = 0;//生成对象的接口,返回的是一个对象,而这些对象都有的一个特点是继承Product这个类,所以返回值用基类的指针
protected:
	std::string mname;
};
class Factory_1:public Factory//工厂一
{
public:
	Factory_1(std::string name):Factory(name){}
	Product* createProduct()//对接口进行实现
	{
		return new ProductA("A");
	}
};
class Factory_2 :public Factory//工厂二
{
public:
	Factory_2(std::string name) :Factory(name){}
	Product* createProduct()
	{
		return new ProductB("B");
	}
};
int main()
{
	Factory* p = new Factory_2("f2");
	Product* pp = p->createProduct();
	pp->operation();
}

运行截图:

 

工厂方法模式的缺点:举个例子,假如我要生产一台电脑,生产一台电脑包括屏幕和外壳,如果只生产一个屏幕或一个外壳不能满足生产一台电脑的要求,所以这里的屏幕和外壳有很强的相关性。而在工厂方法模式中,一个工厂产生一个对象,两者之间没有什么相关性,这就是工厂模式所存在的缺陷。

适用场景:工厂方法模式解决了简单工厂模式规模确定的问题,需要添加一个对象时,只需再添加一个生成这个对象的工厂类,而不会修改原来的代码。适用于规模不固定的场景下。

抽象工厂模式

原理:为了使产品有强的相关性,可以将有相关性的产品在一个工厂中生产。还是上面的例子,有13.3寸和15.6寸的电脑,要生产一台13.3寸的电脑,就需要13.3寸的屏幕和外壳,两者有比较强的相关性,在一个工厂中生产;而13.3寸的屏幕和15.6寸的屏幕又属于一个系列,即产品屏幕。如下图的关系:

特点:有不同族,同一族中有不同产生产品的接口

代码:

class ProductA
{
public:
	ProductA(std::string nm) :name(nm){}
	virtual ~ProductA(){}
	virtual void operation() = 0;
protected:
	std::string name;
};
class ProductA1 :public ProductA//产品A中有一个A1
{
public:
	ProductA1(std::string nm) :ProductA(nm){}
	virtual void operation()
	{
		std::cout << "A1" << std::endl;
	}
};
class ProductA2 :public ProductA//产品A中有一个A2
{
public:
	ProductA2(std::string nm) :ProductA(nm){}
	virtual void operation()
	{
		std::cout << "A2" << std::endl;
	}
};

class ProductB
{
public:
	ProductB(std::string nm) :name(nm){}
	virtual ~ProductB(){}
	virtual void operation() = 0;
protected:
	std::string name;
};
class ProductB1 :public ProductB////产品B中有一个B1
{
public:
	ProductB1(std::string nm) :ProductB(nm){}
	virtual void operation()
	{
		std::cout << "B1" << std::endl;
	}
};
class ProductB2 :public ProductB//产品B中有一个B2
{
public:
	ProductB2(std::string nm) :ProductB(nm){}
	virtual void operation()
	{
		std::cout << "B2" << std::endl;
	}
};
class AbstractFactory
{
public:
	virtual ~AbstractFactory(){}
	virtual ProductA* createProductA() = 0;
	virtual ProductB* createProductB() = 0;
};
class Factory_1 :public AbstractFactory
{
public:
	virtual ProductA* createProductA()
	{
		return new ProductA1("A1");//创建工厂一中的产品A1
	}
	virtual ProductB* createProductB()
	{
		return new ProductB1("B1");//创建工厂一中的产品B1
	}
};
class Factory_2 :public AbstractFactory
{
public:
	virtual ProductA* createProductA()
	{
		return new ProductA2("A2");//创建工厂二中的产品A2
	}
	virtual ProductB* createProductB()
	{
		return new ProductB2("B2");//创建工厂二中的产品B2
	}
};

int main()
{
	AbstractFactory* pf = new Factory_1();
	ProductA* ppa = pf->createProductA();
	ppa->operation();

	ProductB* ppb = pf->createProductB();
	ppb->operation();
	return 0;
}

运行结果截图:

适用场景:产品之间有强的相关性 

猜你喜欢

转载自blog.csdn.net/QX_a11/article/details/89433817