一、什么是抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。简单来说,多个工厂模式的叠加,即有多个工厂,每个工厂可以产生多种产品,而实际使用过程中,只挑一个工厂,产生一个产品,对于多个工厂、产品的功能进行抽象,使用统一的接口完成这件事:只挑一个工厂,产生一个产品。具体什么是工厂模式,请看上一文章:https://blog.csdn.net/LittleLittleFish_xyg/article/details/83311004
二、代码结构实现抽象工厂模式
此模式中的两个关键点:有抽象工厂,有抽象产品。而具体的产品类则是由具体的工厂类来实现“生产”功能。
抽象工厂的实现:
抽象工厂,只定义了一个抽象方法,用来创建产品对象
class Product;
class Factory
{
public:
virtual ~Factory()=0;
virtual Product* CreateProduct()=0;
protected:
Factory();
private:
};
具体工厂类,对父类创建产品的方法实现具体的生产过程
class ConcreteFactoty:public Factory
{
public:
ConcreteFactoty();
~ConcreteFactoty();
Product* CreateProduct();
private:
};
抽象产品类的编码如下,具有某些属性方法:
class Product
{
public:
virtual~Product()=0;
virtual void someFunction()=0;
protected:
Product();
private:
};
具体产品类的实现:
class ConcreteProduct :public Product
{
public:
~ConcreteProduct();
void someFunction()
{
//具体实现某些功能
};
private:
ConcreteProduct();
friend class ConcreteFactoty;
};
其实抽象工厂模式,仅仅是对工厂方法进行了拓展,对工厂类进行了抽象,即可以派生多个工厂类,从而实现工厂与产品的个性化定制
三、代码实现的注意事项
1、两个抽象类的析构函数的写法,在实现类释放内存时同时释放抽象类的内存空间
2、抽象产品和具体产品类的构造函数需要保护起来,否则能new出来,就失效了
3、由于具体产品的构造函数被保护,具体工厂要实例化具体产品类,就必须添加友元
四、抽象工厂模式的使用方法
在实际开发过程中有时候会遇到一些个性化定制问题的需求,比如很多人喜欢玩王者荣耀,游戏中很多皮肤,其实也是个个性化定制的需求,在这简单模拟一下(具体王者荣耀是否用这种模式,不得而知,仅仅个人猜测)
描述:每套皮肤,有衣服、装备、鞋子,假设设计过程是分给三个程序员完成的,在这里三个程序员就好比三个工厂。而衣服,装备,鞋子就是具体的产品类。那么在个性化的过程中,具体的一个程序员设计出具体的一款产品,就是他的任务,也是抽象工厂方法的实现过程,此时把抽象工厂类比喻成一个英雄,具体工厂类比喻成具体的英雄刘备。
抽象工厂的实现:
一个英雄的皮肤有衣服、装备、鞋子组成
class Clothes;
class Equipment;
class Shoes;
class Hero
{
public:
virtual ~Hero() = 0;
virtual Clothes* CreateClothes() = 0;
virtual Equipment* CreateEquipment() = 0;
virtual Shoes* CreateShoes() = 0;
protected:
Hero();
private:
};
具体的英雄,比如刘备:
class LiuBei:public Hero
{
public:
LiuBei();
~LiuBei();
Clothes* CreateClothes() ;
Equipment* CreateEquipment();
Shoes* CreateShoes();
protected:
private:
};
抽象的产品类
为了简单描述,仅仅定义皮肤类 的一个颜色属性,这里有三个抽象产品类,即衣服、装备、鞋子的抽象,具体是什么颜色,由子类具体实现
class abstractClothes
{
public:
virtual ~abstractClothes() {};
virtual void color() = 0;
private:
abstractClothes();
};
class abstractEquipment
{
public:
virtual ~abstractEquipment() {};
virtual void color() = 0;
private:
abstractEquipment();
};
class abstractShoes
{
public:
virtual ~abstractShoes() {};
virtual void color() = 0;
private:
abstractShoes();
};
具体产品类的实现
class Clothes:public abstractClothes
{
public:
~Clothes() {};
void color();
private:
Clothes();
};
class Equipment :public abstractEquipment
{
public:
~Equipment() {};
void color();
private:
Equipment();
};
class Shoes :public abstractShoes
{
public:
~Shoes() {};
void color();
private:
Shoes();
};
不同的皮肤类,可以扩展不一样的颜色,尺寸,风格等具体的产品类,通过具体工厂生成,从而实现个性化定制功能,细心的的童鞋应该看出来上面是漏了好几行友元的,偷懒了一下,莫见怪。
五、优缺点
优点:对产品族进行约束,而不必专门引入一个新的类来进行管理
缺点:产品族的扩展将是一件十分费力的事情,如上面编码,如果新加一个特性和一个工厂,就要拓展成乘积倍的编码(n个工厂,m个产品,要编写nxm个类),挺痛苦的过程