设计模式之工厂模式二三事
2013-05-15 00:25
141 查看
很久没有写过C++的项目了,最近看了看设计模式,对于工厂模式略有心得,故写出来分享。
工厂模式大致分为三类:简单工厂模式、工厂方法模式、抽象工厂模式
OK,上图说明,还是用网上流行的做菜比喻。
无工厂情况
我想吃红烧鱼,没问题,我自己做(new):
Fish *f = new BraisingFish; //自己做红烧鱼
f->Delicious(); //美味啊
可是做了几天后,我不想自己做(new)了,太累,咋办?建一个烹饪鱼工厂给我做鱼。
简单工厂模式
我想吃红烧鱼,现在不用自己做(new)了,直接去找烹饪工厂,烹饪工厂给我做红烧鱼(CookFish)
CookFishFactory *cff = new CookFishFactory; //烹饪工厂
Fish *f = cff->CookFish(); //烹饪工厂给我做红烧鱼
f->Delicious(); //美味啊
优点:1、以后都不用自己做红烧鱼了,直接让工厂做。(解决了代码中大量New的问题)。
2、工厂做鱼的方式更灵活,我什么都不用管了。
缺点:下面就说。
工厂方法模式
天天都吃红烧鱼,扛不住了,我要吃清蒸鱼,怎么办?自己做?太累了,还得学清蒸鱼的做法,改进烹饪工厂?不行,不能改进工厂(开闭法则),怎么办?!无解啊,看来简单工厂模式不行,我得换一种模式,不能由烹饪鱼工厂来直接做红烧鱼, 我专门建一个烹饪红烧鱼的工厂,让烹饪鱼工厂将烹饪红烧鱼的工作外包给烹饪红烧鱼的工厂。
我想吃红烧鱼,先找烹饪鱼工厂,烹饪鱼工厂将工作外包给烹饪红烧鱼的工厂:
CookFishFactory *cff = new CookBraisingFishFactory;
Fish *f = cff->CookFish();
f->Delicious();
那么我想吃清蒸鱼咋办?!
增加一个清蒸鱼的外包工厂
这样当我想吃清蒸鱼了,
CookFishFactory *cf = new CookSteamedFactory;
FoodProduct *fp = cf->CookFood();
这样,在不违背开闭法则的前提下解决了简单工厂模式的缺点。
优点:1、简单工厂模式具有的优点。
2、解决了简单工厂模式的缺点。
缺点:下面说。
抽象工厂模式
天天吃鱼,不行,腻了,想换换口味,吃点猪肉吧,怎么办?在工厂方法模式下,我可以再建一个烹饪猪肉的工厂,然后下面有烹饪红烧肉啊,清蒸肉啊等等,这当然可以,但为了吃猪肉,我得建好几个工厂,譬如红烧肉工厂、清蒸肉工厂,有没有办法不建这么多工厂呢?!
怀着这个想法,我发现不管是鱼还是肉,都有几种相同的做法,譬如红烧,清蒸。
横坐标表示肉类,有鱼肉、猪肉(产品等级结构),纵坐标表示制作方法(产品族),可清蒸,可红烧,这样,我可以再次设计我的工厂,分为红烧工厂和清蒸工厂,一个工厂可以做两种肉类(抽象工厂)。
如果我想吃红烧肉,我可以这样做:
CookFactory *cf = new CookBraisingFactory;
Pork *p = cf->CookPork();
p->Delicious();
如果我想吃清蒸肉,这样做:
CookFactory *cf = new CookSteamedFactory;
Pork *p = cf->CookPork();
p->Delicious();
红烧鱼做法:
CookFactory *cf = new CookBraisingFactory;
Fish *f = cf->CookFish();
f->Delicious();
清蒸鱼做法:
CookFactory *cf = new CookSteamedFactory;
Fish *f = cf->CookFish();
f->Delicious();
这样,如果我又想出一种新的做法,譬如水煮的时候,我可以新建一个水煮的工厂,同时做水煮鱼和水煮肉。
但是,如果我想增加一种肉类,比如鸡肉咋办?!没辙。
那么抽象工厂模式有什么优点呢?因为我吃的肉类是有限的,就鸡肉、鱼肉、猪肉、牛肉等等,轻易不会再增加肉的类型了,但各种肉的制作方法是有不同的,而且可以增加,比如油闷,爆炒等等,什么时候我想出了一种新做法,直接增加一个相应的工厂就行,不用再根据不同的原料与不同的做法增加不同的工厂。
OK,不说吃了,拿IT举个例子吧,譬如QT图形库,图形库由很多组件组成,有button,view,widget等等,这些东西就相当于我们的猪肉、鱼肉、牛肉等等,QT是跨平台的,可以在windows上跑,可以在linux上跑,也可以在OSX上跑,这些平台,就相当于我们的红烧工厂、清蒸工厂、水煮工厂。如果我们需要增加一个产品族,譬如在Solaris上跑的话,很容易,增加一个工厂就行,不会违背开闭法则,但如果想增加一个产品等级结构,譬如增加一个控件,就很麻烦了,需要修改所有的工厂,会违背开闭法则。
优点:很容易增加产品族,不违背开闭法则。
缺点:难以添加产品等级结构,会违背开闭法则。
工厂模式大致分为三类:简单工厂模式、工厂方法模式、抽象工厂模式
OK,上图说明,还是用网上流行的做菜比喻。
无工厂情况
我想吃红烧鱼,没问题,我自己做(new):
Fish *f = new BraisingFish; //自己做红烧鱼
f->Delicious(); //美味啊
可是做了几天后,我不想自己做(new)了,太累,咋办?建一个烹饪鱼工厂给我做鱼。
简单工厂模式
我想吃红烧鱼,现在不用自己做(new)了,直接去找烹饪工厂,烹饪工厂给我做红烧鱼(CookFish)
CookFishFactory *cff = new CookFishFactory; //烹饪工厂
Fish *f = cff->CookFish(); //烹饪工厂给我做红烧鱼
f->Delicious(); //美味啊
优点:1、以后都不用自己做红烧鱼了,直接让工厂做。(解决了代码中大量New的问题)。
2、工厂做鱼的方式更灵活,我什么都不用管了。
缺点:下面就说。
工厂方法模式
天天都吃红烧鱼,扛不住了,我要吃清蒸鱼,怎么办?自己做?太累了,还得学清蒸鱼的做法,改进烹饪工厂?不行,不能改进工厂(开闭法则),怎么办?!无解啊,看来简单工厂模式不行,我得换一种模式,不能由烹饪鱼工厂来直接做红烧鱼, 我专门建一个烹饪红烧鱼的工厂,让烹饪鱼工厂将烹饪红烧鱼的工作外包给烹饪红烧鱼的工厂。
我想吃红烧鱼,先找烹饪鱼工厂,烹饪鱼工厂将工作外包给烹饪红烧鱼的工厂:
CookFishFactory *cff = new CookBraisingFishFactory;
Fish *f = cff->CookFish();
f->Delicious();
那么我想吃清蒸鱼咋办?!
增加一个清蒸鱼的外包工厂
这样当我想吃清蒸鱼了,
CookFishFactory *cf = new CookSteamedFactory;
FoodProduct *fp = cf->CookFood();
这样,在不违背开闭法则的前提下解决了简单工厂模式的缺点。
优点:1、简单工厂模式具有的优点。
2、解决了简单工厂模式的缺点。
缺点:下面说。
抽象工厂模式
天天吃鱼,不行,腻了,想换换口味,吃点猪肉吧,怎么办?在工厂方法模式下,我可以再建一个烹饪猪肉的工厂,然后下面有烹饪红烧肉啊,清蒸肉啊等等,这当然可以,但为了吃猪肉,我得建好几个工厂,譬如红烧肉工厂、清蒸肉工厂,有没有办法不建这么多工厂呢?!
怀着这个想法,我发现不管是鱼还是肉,都有几种相同的做法,譬如红烧,清蒸。
横坐标表示肉类,有鱼肉、猪肉(产品等级结构),纵坐标表示制作方法(产品族),可清蒸,可红烧,这样,我可以再次设计我的工厂,分为红烧工厂和清蒸工厂,一个工厂可以做两种肉类(抽象工厂)。
如果我想吃红烧肉,我可以这样做:
CookFactory *cf = new CookBraisingFactory;
Pork *p = cf->CookPork();
p->Delicious();
如果我想吃清蒸肉,这样做:
CookFactory *cf = new CookSteamedFactory;
Pork *p = cf->CookPork();
p->Delicious();
红烧鱼做法:
CookFactory *cf = new CookBraisingFactory;
Fish *f = cf->CookFish();
f->Delicious();
清蒸鱼做法:
CookFactory *cf = new CookSteamedFactory;
Fish *f = cf->CookFish();
f->Delicious();
这样,如果我又想出一种新的做法,譬如水煮的时候,我可以新建一个水煮的工厂,同时做水煮鱼和水煮肉。
但是,如果我想增加一种肉类,比如鸡肉咋办?!没辙。
那么抽象工厂模式有什么优点呢?因为我吃的肉类是有限的,就鸡肉、鱼肉、猪肉、牛肉等等,轻易不会再增加肉的类型了,但各种肉的制作方法是有不同的,而且可以增加,比如油闷,爆炒等等,什么时候我想出了一种新做法,直接增加一个相应的工厂就行,不用再根据不同的原料与不同的做法增加不同的工厂。
OK,不说吃了,拿IT举个例子吧,譬如QT图形库,图形库由很多组件组成,有button,view,widget等等,这些东西就相当于我们的猪肉、鱼肉、牛肉等等,QT是跨平台的,可以在windows上跑,可以在linux上跑,也可以在OSX上跑,这些平台,就相当于我们的红烧工厂、清蒸工厂、水煮工厂。如果我们需要增加一个产品族,譬如在Solaris上跑的话,很容易,增加一个工厂就行,不会违背开闭法则,但如果想增加一个产品等级结构,譬如增加一个控件,就很麻烦了,需要修改所有的工厂,会违背开闭法则。
优点:很容易增加产品族,不违背开闭法则。
缺点:难以添加产品等级结构,会违背开闭法则。
相关文章推荐
- java 设计模式 学习笔记(四)工厂模式
- 【设计模式】简单工厂模式
- 23种设计模式之工厂方法
- 深入浅出设计模式-004:工厂模式(Factory Pattern)
- 设计模式之简单工厂的理解
- Java设计模式之工厂模式(Factory模式)介绍
- 设计模式之1---简单工厂模式
- 常用设计模式总结--抽象工厂
- java设计模式之工厂方法模式以及简单工厂模式还有抽象工厂模式
- 设计模式[2]-旧话重提之工厂模式
- 设计模式 工厂模式 从卖肉夹馍说起
- 设计模式 --- 工厂模式
- php设计模式之工厂模式浅析
- 工厂设计模式
- Python设计模式之工厂模式
- Php设计模式之工厂模式(三)【抽象工厂模式 AbstractFactory】
- java设计模式-工厂模式
- Android设计模式之工厂模式 Factory
- 设计模式(四)—工厂方法(创建型)
- 设计模式-工厂方法(Demo)