文章目录
- 1. 解决问题
- 2. 应用场景
- 3. 实现如下:
- C++实现
- C语言实现
- 4. 缺点
1. 解决问题
在工厂方法模式中,我们卖衣服。此时我们为每一种衣服创建不同的工厂,帽子有一个工厂专门创建,裤子有一个工厂专门创建,T恤有一个工厂专门创建。这样的方式保证了代码设计的开闭原则(对扩展开发,对修改关闭),解决了简单工厂模式中暴露的问题。
但是又凸显了新的问题,假如现在优衣库这个大工厂 里面需要生产不同的种类的衣服,我们需要创建一堆工厂。同时香蕉共和国 这个另一个大工厂也需要生产不同种类的衣服,我们又需要创建一堆工厂。在这种情况下,代码会增加很多重复逻辑。
于是抽象工厂模式推出,将帽子封装为一个工厂, 支持生产优衣库的帽子和香蕉共和国的帽子。将裤子封装为另一个工厂,用来生产优衣库的裤子和香蕉共和国的裤子。
2. 应用场景
- 对象之间存在关联,两个对象使用同一个工厂生产,降低程序复杂度,减少不必要的重复逻辑。
- 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋
- 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构
- 对象数量比较庞大,维护多个工厂则程序的复杂度过高,由工厂方法模式变更为抽象工厂模式
3. 实现如下:
C++实现
实现功能:仍然是生产衣服,我们使用抽象工厂模式 将优衣库的帽子和香蕉共和国的帽子统一生产,将优衣库的裤子和香蕉共和国的裤子统一生产。
#include <iostream>
using namespace std;
class Hat{
public:
virtual void createHat(void) = 0;
virtual ~Hat(){}
};
/*优衣库的帽子*/
class kuHat: public Hat {
public:
kuHat(){
cout << "kuHat::kuHat()" << endl;
}
virtual void createHat(void) {
cout << "kuHat::createHat()" << endl;
}
~kuHat(){
cout << "kuHat::delete()" << endl;
}
};
/*香蕉共和国的帽子*/
class bananHat: public Hat{
public:
bananHat(){
cout << "bananHat::bananHat()" << endl;
}
virtual void createHat(void) {
cout << "bananHat::createHat()" << endl;
}
~bananHat(){
cout << "bananHat::delete()" << endl;
}
};
class Paths{
public:
virtual void createPaths(void) = 0;
virtual ~Paths(){}
};
/*优衣库的裤子*/
class kuPaths: public Paths{
public:
kuPaths(){
cout << "kuPaths::kuPaths()" << endl;
}
virtual void createPaths(void) {
cout << "kuPaths::createPaths()" << endl;
}
~kuPaths(){
cout << "kuPaths::delete()" << endl;
}
};
/*香蕉共和国的裤子*/
class bananPaths: public Paths{
public:
bananPaths(){
cout << "bananPaths::bananPaths()" << endl;
}
virtual void createPaths(void) {
cout << "bananPaths::createPaths()" << endl;
}
~bananPaths(){
cout << "bananPaths::delete()" << endl;
}
};
/*抽象工厂类*/
class Factory {
public:
virtual Hat *createHat() = 0;
virtual Paths *createPaths() = 0;
};
/*优衣库的工厂,用来创建优衣库的衣服*/
class FactoryKu: public Factory{
public:
Hat *createHat(){
return new kuHat();
}
Paths *createPaths(){
return new kuPaths();
}
};
/*香蕉共和国的工厂,用来创建香蕉共和国的衣服*/
class FactoryBanan: public Factory {
public:
Hat *createHat(){
return new bananHat();
}
Paths *createPaths() {
return new bananPaths();
}
};
int main() {
/*创建一个优衣库的工厂,进行优衣库的衣服的生产,包括裤子和帽子*/
Factory *factory1 = new FactoryKu();
Hat *kuhat = factory1 -> createHat();
Paths *kupaths = factory1 -> createPaths();
kuhat -> createHat();
kupaths -> createPaths();
if(factory1) {
delete factory1;
factory1 = NULL;
}
if(kuhat) {
delete kuhat;
kuhat = NULL;
}
if(kupaths) {
delete kupaths;
kupaths = NULL;
}
return 0;
}
编译运行如下
kuHat::kuHat()
kuPaths::kuPaths()
kuHat::createHat()
kuPaths::createPaths()
kuHat::delete()
kuPaths::delete()
C语言实现
实现功能:工厂商店分别 售卖白苹果、红苹果、白葡萄、红葡萄
/*C语言实现抽象工厂模式*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
enum {WHITE,RED};
/*苹果基类*/
typedef struct _Apple {
void (*print_apple)(void);
}Apple;
/*葡萄基类*/
typedef struct _Grape {
void (*print_grape)(void);
}Grape;
void print_white_apple(void)
{
printf("I'am a white apple!\n");
return;
}
void print_red_apple(void)
{
printf("I'am a red apple!\n");
return;
}
void print_white_grape(void)
{
printf("I'am a white grape!\n");
return;
}
void print_red_grape(void)
{
printf("I'am a red grape!\n");
return;
}
/*水果商店*/
typedef struct _FruitShop {
Apple * (*sell_apple)(void);
Grape * (*sell_grape)(void);
}FruitShop;
Apple* sell_white_apple(void)
{
Apple* tmp_apple = (Apple*)malloc(sizeof(Apple));
assert(NULL != tmp_apple);
tmp_apple->print_apple = print_white_apple;
return tmp_apple;
}
Apple* sell_red_apple(void)
{
Apple* tmp_apple = (Apple*)malloc(sizeof(Apple));
assert(NULL != tmp_apple);
tmp_apple->print_apple = print_red_apple;
return tmp_apple;
}
Grape* sell_white_grape(void)
{
Grape* tmp_grape = (Grape*)malloc(sizeof(Grape));
assert(tmp_grape != NULL);
tmp_grape->print_grape = print_white_grape;
return tmp_grape;
}
Grape* sell_red_grape(void)
{
Grape* tmp_grape = (Grape*)malloc(sizeof(Grape));
assert(tmp_grape);
tmp_grape->print_grape = print_red_grape;
return tmp_grape;
}
/*工厂商店,卖不同颜色的苹果和葡萄*/
FruitShop* create_fruit_shop(int color)
{
FruitShop* fruitshop = (FruitShop*)malloc(sizeof(FruitShop));
assert(fruitshop != NULL);
if (color == WHITE) {
fruitshop->sell_apple = sell_white_apple;
fruitshop->sell_grape = sell_white_grape;
}
else if (color == RED) {
fruitshop->sell_apple = sell_red_apple;
fruitshop->sell_grape = sell_red_grape;
}
return fruitshop;
}
int main()
{
FruitShop* fruitshop = create_fruit_shop(RED);
Apple *ap = fruitshop->sell_apple();
Grape *gp = fruitshop->sell_grape();
ap->print_apple();
gp->print_grape();
if (ap != NULL) {
free(ap);
}
if (gp != NULL) {
free(gp);
}
if (fruitshop != NULL) {
free(fruitshop);
}
return 0;
}
I'am a red apple!
I'am a red grape!
4. 缺点
- 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则。(按照如上C++代码,我们买衣服,当我们增加一种衣服:裙子的时候,只需要增加一个新的生产裙子的工厂就可以,不需要修改原的衣服种类的代码)
- 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。(当我们又增加了名创优品的种类时,我们之前所有的类包括:hat,Paths,还有对应的工厂类都需要修改 )