工厂设计模式
工厂设计模式提供了生成对象的最佳方法,这一设计模式的优势就在于屏蔽了生成对象复杂的过程。有三种工厂模式,分别为:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
原理:工厂生产产品,而这里的产品指的就是对象。在简单工厂模式中,用一个标识对应一个对象的方法,要生成某一产品时,只需要传入对应的标识,这样做的优势是当需要生产大量的对象时,不需要对对象名进行记忆,并且屏蔽了生产对象的复杂过程。
特点:所有对象在一个工厂生产
代码:
#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;
}
运行结果截图:
适用场景:产品之间有强的相关性