首页 > 编程模式 之美 -- 抽象工厂模式

编程模式 之美 -- 抽象工厂模式

文章目录

        • 1. 解决问题
        • 2. 应用场景
        • 3. 实现如下:
          • C++实现
          • C语言实现
        • 4. 缺点

1. 解决问题

在工厂方法模式中,我们卖衣服。此时我们为每一种衣服创建不同的工厂,帽子有一个工厂专门创建,裤子有一个工厂专门创建,T恤有一个工厂专门创建。这样的方式保证了代码设计的开闭原则(对扩展开发,对修改关闭),解决了简单工厂模式中暴露的问题。

但是又凸显了新的问题,假如现在优衣库这个大工厂 里面需要生产不同的种类的衣服,我们需要创建一堆工厂。同时香蕉共和国 这个另一个大工厂也需要生产不同种类的衣服,我们又需要创建一堆工厂。在这种情况下,代码会增加很多重复逻辑。

于是抽象工厂模式推出,将帽子封装为一个工厂, 支持生产优衣库的帽子和香蕉共和国的帽子。将裤子封装为另一个工厂,用来生产优衣库的裤子和香蕉共和国的裤子。

2. 应用场景

  • 对象之间存在关联,两个对象使用同一个工厂生产,降低程序复杂度,减少不必要的重复逻辑。
  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构
  • 对象数量比较庞大,维护多个工厂则程序的复杂度过高,由工厂方法模式变更为抽象工厂模式

3. 实现如下:

C++实现

实现功能:仍然是生产衣服,我们使用抽象工厂模式 将优衣库的帽子和香蕉共和国的帽子统一生产,将优衣库的裤子和香蕉共和国的裤子统一生产。

#include 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 
#include 
#include 
#include 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!
");return;
}void print_red_apple(void)
{ printf("I'am a red apple!
");return;
}
void print_white_grape(void)
{ printf("I'am a white grape!
");return;
}
void print_red_grape(void)
{ printf("I'am a red grape!
");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. 缺点

抽象工厂模式 的扩展有一定的“开闭原则”倾向性:

  1. 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则。(按照如上C++代码,我们买衣服,当我们增加一种衣服:裙子的时候,只需要增加一个新的生产裙子的工厂就可以,不需要修改原的衣服种类的代码)
  2. 当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。(当我们又增加了名创优品的种类时,我们之前所有的类包括:hat,Paths,还有对应的工厂类都需要修改 )

更多相关:

  • 因为函数参数是按值传递的,所以要想改变变量,必须传递地址。 二级指针实际上就是指针变量的地址,如果传递二级指针,函数声明必须写**。 (void**)&必须是本质上就是指针变量的地址才可以做这样的转换,并不是说把一个一级指针也可以转换,void**的本质是标识一个二级指针。 &data就是(默认数据类型 **)&data,(void...

  • 转载于:http://blog.csdn.net/u012819339/article/details/50654764   实体作品请参看优酷视频。 若以上链接点击无效请把该链接地址复制到浏览器地址栏 http://v.youku.com/v_show/id_XODYzODczNzQ4.html 说明: 该作品为arvik于2014...

  • - (void)viewDidLoad {[super viewDidLoad];NSLog(@"我在玩手机");NSLog(@"手机没电了");[self chargeMyIphone:^{NSLog(@"出门逛街");}];NSLog(@"我在看电视"); }-(void)chargeMyIphone:(void(^)(void...

  • http://stackoverflow.com/questions/150446/how-do-i-detect-when-someone-shakes-an-iphone 我的实现(基于Eran Talmor): 没必要application.applicationSupportsShakeToEdit = YES; Set th...

  • 简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。 本文是本人对这三种模式学习后的一个小结以及对他们之间的区别的理解。   简单工厂 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。...

  • 简介 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。 不同点 为了更清晰地理解抽象工厂模式,需要先引入两个概念:产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是CPU,其子类有intel...

  • 工厂方法模式: 一个抽象产品类,可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类只能创建一个具体产品类的实例。 抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。 区别:...

  • 又重头想了一下还是以配电脑为例最开始的时候,需要电脑,你得自己去生产电脑的每一个组件,例如你要cpu 就得自己生产cpu 要主板就得自己生产主板。于是出现 简单工厂模式在简单工厂模式中,定义一个返回接口,然后所有的组件实例都从这个工厂中产生例: 工厂---------生产硬件 硬件----------...