一,产品等级结构与产品族
我们先给出以下的例子:
国美工厂 生产(国美冰箱,国美空调,国美洗衣机)
美的工厂 生产(美的冰箱,美的空调,美的洗衣机)
海尔工厂 生产(海尔冰箱,海尔空调,海尔洗衣机)
产品等级结构
产品的继承结构
例如上图中:洗衣机就是一个产品等级结构
由洗衣机派生出国美洗衣机,美的洗衣机,海尔洗衣机,它们都属于洗衣机这一产品等级结构
由冰箱派生出国美冰箱,美的冰箱,海尔冰箱,它们都属于冰箱这一产品等级结构
由空调派生出国美空调,美的空调,海尔空调,它们都属于空调这一产品等级结构
产品族
一组不同产品等级结构的产品
例如上图中:国美就是一个产品族
由冰箱产品体系结构的国美冰箱,空调产品体系结构的国美空调,洗衣机产品体系结构的国美洗衣机组成国美这一产品族
产品等级结构与产品族的关系
从图中纵向来看,不管是海尔空调、美的空调、国美空调他们都是同一种产品等级结构(空调)的不同品牌(产地)的产品
从横向来看海尔产品族、美的产品族、国美产品族,组成他们的产品等级结构都是相同的(都是由冰箱,空调,洗衣机组成)
一组相同产品等级结构的产品可以通过简单工厂模式或工厂方法模式表示:如海尔空调、格力空调、美的空调、国美空调等他们都是空调。
产品族可以用抽象工厂模式表示
二,定义
抽象工厂模式:创建型模式之一,抽象工厂模式是以一个超级工厂创建其他工厂。抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构(产品族)。
三,类图
四,成员职责
抽象产品角色:具体工厂所创建所有对象的父类,负责定义所有实例共有的公共接口
具体产品角色:具体工厂所创建的实例对象,这些对象往往拥有相同的基类
抽象工厂角色:抽象工厂是工厂方法模式的核心,在抽象工厂中声明了工厂方法,负责返回一个对象
具体工厂角色:是抽象工厂的子类,实现了抽象工厂声明的工厂方法,并可以由客户端调用,返回一个实例
五,实现
有一个苹果的抽象类,有中国苹果和美国苹果继承于这个抽象类,并且实现抽象方法
还有一个香蕉的抽象类,由中国香蕉和美国香蕉继承于这个抽象类,并且实现抽象方法
有一个抽象工厂类(针对产品族(由苹果和香蕉构成)),其中声明了两个工厂方法制造苹果和制造香蕉
由中国工厂继承于这个抽象类,实现了工厂方法:制造中国苹果和制造中国香蕉
和美国工厂继承于这个抽象类,实现了工厂方法:制造美国苹果和制造美国香蕉
客户可以根据选择不同的工厂获得不同的苹果或香蕉
抽象苹果接口(抽象产品类)
class apple
{
public:
virtual void soldapple() = 0;
};
中国苹果(具体产品类)
class china_apple : public apple
{
public:
void soldapple() override
{
cout << "中国苹果被买了" << endl;
}
};
美国苹果(具体产品类)
class usa_apple : public apple
{
public:
void soldapple() override
{
cout << "美国苹果被买了" << endl;
}
};
抽象香蕉接口(抽象产品类)
class banana
{
public:
virtual void soldbanana() = 0;
};
中国香蕉(具体产品类)
class china_banana : public banana
{
public:
void soldbanana() override
{
cout << "中国香蕉被买了" << endl;
}
};
美国香蕉(具体产品类)
class usa_banana : public banana
{
public:
void soldbanana() override
{
cout << "美国香蕉被买了" << endl;
}
};
抽象工厂接口(抽象工厂类)
class factory
{
public:
virtual apple* createapple() = 0;
virtual banana* createbanana() = 0;
};
中国工厂(具体工厂类)
class china_factory : public factory
{
public:
apple* createapple() override
{
return new china_apple;
}
banana* createbanana() override
{
return new china_banana;
}
};
美国工厂(具体工厂类)
class usa_factory : public factory
{
public:
apple* createapple() override
{
return new usa_apple;
}
banana* createbanana() override
{
return new usa_banana;
}
};
测试方法与主函数
void client()
{
factory* f = nullptr;
apple* a = nullptr;
banana* b = nullptr;
f = new china_factory;
a = f->createapple();
b = f->createbanana();
a->soldapple();
b->soldbanana();
delete f;
f = new usa_factory;
a = f->createapple();
b = f->createbanana();
a->soldapple();
b->soldbanana();
delete f;
}
int main()
{
client();
return 0;
}
六,优缺点
优点:
在应用层隔离具体产品的代码,客户端不需要关心产品的创建
将一个系列的产品(产品族),统一到一起创建
缺点:
如果要增加新产品,会对原有代码进行大量修改
七,适用场景
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
强调一系列相关的产品对象(属于同一产品族)一起使用,创建对象需要大量重复的代码