工厂模式

一、工厂模式定义:
根据给出的信息创建特定类的实例,以达到程序解耦的目的。
二、使用场景目的:
一般用在创建对象的情况比较复杂,在整个程序的开发及运维阶段,无法预知将要
创建哪些类的实例。将直接创建对象的方式改为从工厂中获取,达到解耦的目的。
举个例子:在人类文明尚且处于蒙昧的阶段,我们需要某种水果时,唯一的办法也
许就是自己去摘取,需要其它某些食物时,也同样如此,这样严重阻碍了生产力的
发展。随着社会的进步,出现了交换行为,进而出现了社会分工。有专门负责种植
水果的人,专门负责贩卖水果的人(单一职责原则)。这样尚嫌不够,我们想吃葡
萄的时候,不一定非要去找专门贩卖葡萄的商贩,通常一个水果商会贩卖多种水
果,我们仅需要告诉他我们想要什么类型的水果,然后由他向我们提供即可,至于
每一种水果是怎么来的,则与我们无关。我们不需要关心水果是产自哪棵果树、以
及这颗果树是怎么管理的。这就是工厂模式的思想。这是政治经济学的一个例子,
不属于本章的范畴,但它很能说明编程中的问题。如果想要更深入的了解,请参看
亚当斯密的《国富论》第一卷:论分工。之所以举这个例子是为了说明:政治经济
学的方法论是哲学的,计算机科学的方法论也同样是哲学的。我们不应该执着于具
体的实现,而应该具备某些思想,这些思想是解决问题的源泉。
三、工厂模式分类:
1、简单工厂模式:
简单工厂模式实现起来尤为简单,以至于很多人不把它归纳到工厂模式中来。但
它确是工厂模式的一种。例如几何学中对于钝角的定义如下:“大于直角的角叫做
钝角”,那么只要符合这个定义的我们都可以称之为钝角。简单工厂模式也一样,
不能因为它过于简单,而排除在工厂模式之外。同样的,我们也可以使用其它方
法实现工厂模式,只要它能够达到解耦的目的,我认为这些都是可行的。我会牢
记一个原则:能够最简单、最直接的达到目的的时候,我不会去走任何曲折的道
路。
代码:

image.png

该接口提供了一个抽象的水果品类,用于实现多态。
image.png

image.png

image.png

以上三个具体的苹果、香蕉、桃子实现了水果接口,也就是说,它们都是水果,具有同一个类型。
image.png

在水果工厂中使用了一个枚举类,用于定义水果的类型。还有一个购买水果的方法,传入相应的水果类型信息,获取特定水果的实例。
image.png

至此一个简单工厂模式就实现了,我认为情况不是特别复杂的情况下,使用这种方式就很大程度上做到了代码的解耦。当然这种方式也是有它的缺点的:如果我们要水果工厂再多生产几种水果,那么不可避免的需要添加枚举类型、需要在购买水果方法中多几个case语句。这样的做法显然违背了开闭原则,也不够优雅。但是使用反射的方式呢?
下面我们改造一下FruitFactory类:
image.png

image.png

现在工厂类只存在一个购买水果的方法,并且它的入参发生了变化:它不再需要一个水果的枚举类型,而是需要传入一个实现了水果接口的任意类型的class对象。现在这个工厂已经具备了一种动态扩展的性质,如果我们需要添加新的水果,仅仅让这个新的水果类实现水果接口即可,无须增加或修改任何代码,已经可以从工厂类中获取任意水果类型的实例了。我个人认为这是简单工厂模式完美的实现,虽然这个工厂类仅仅使用了几行代码。但是我们想想之前的那个原则(如果认同的话):能够使用最直接、最简单的方式达到目的,绝不采用任何曲折繁杂的方式去实现。当然,这种实现方式也并非无可挑剔,比如:如果构造实例时需要初始化参数、构造器私有等等。但这是工厂模式都能够遇到的问题,使用这种方式也是可以进行解决的。spring中就大量使用了反射来创建对象,我认为这种方式之所以没有被人提及,不过是因为过于简单罢了。
2、工厂方法模式
image.png

定义一个水果工厂接口,里面仅有购买水果这一抽象行为,至于买什么水果,要在具体工厂里面去实现。
image.png

image.png

新建两个具体的水果工厂类,都实现水果工厂接口。
image.png

这种模式解决了需要创建对象种类非常多、且创建对象方式复杂的情况下,频繁修改购买水果接口,增加购买水果方法的复杂度。很大程度上遵守了开闭原则。但是很显然,这种方式不过是把方法的复杂度转移到了类级别上,如果项目复杂程度较高时,这种方式无疑是一种比较好的选择。这种方式的缺点也是很明显的:针对每一个具体产品创建一个工厂类,成本是不是太高了?
3、抽象工厂模式:
接下来我们想象会遇到这样一种场景:我们购买各种水果来制作不同的水果蛋糕。现
在仅仅是购买水果还是不够的,我们还需要购买奶油及其它材料,现在修改一下代
码:
image.png

定义一个抽象接口,并提供一个获取奶油种类名称的方法。
image.png

image.png

定义一个动物淡奶油类,然后蛋糕制作商为了节约成本,还会选择人造奶油作为原料。现在这两种材料都实现了奶油接口,因此是无差别的。这两种材料制作的蛋糕都叫做奶油蛋糕。
image.png

定义一个抽象工厂类。
image.png

一个具体的水果工厂,继承了抽象工厂,并提供根据传入的class对象,动态获取水果的方法。
image.png

具体的奶油工厂,实现了获取奶油的抽象方法。
image.png

创建一个工厂建造者类,根据传入的class对象,动态获取工厂实例。获取工厂实例的方法仍然使用反射动态获取。
image.png

测试类中,根据特定工厂类的class对象,获取相应的工厂对象,并且根据具体的水果及奶油类型,获取到了具体的水果,最后制作成了廉价的“苹果人造奶油蛋糕”。

结论:
抽象工厂模式用于解决多个不同的类实例的创建,其可扩展性要优于简单工厂模式
及工厂方法模式。但就其实现方式来说,也比其他工厂模式要更加复杂。而且需要
针对每一个类创建一个工厂实现类,并在抽象工厂中加入获取具体工厂的方法。工
厂模式充分利用了java多态的特性,是利用多态进行解耦的一个比较好的实现,也
是依赖倒置原则的一种体现。但在使用时应该根据具体情况来判断使用哪一种模式
更好,毕竟不能像本章的demo一样,为了“输出一句hello word”而实现一个抽象工
厂模式。本章的demo仅仅是一个例子,用来说明工厂模式的具体实现。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。通常我们所说的工厂模式是指工厂方法模...
    zfylin阅读 1,309评论 0 7
  • 1.接口基础回顾 设计模式六大原则,其中依赖倒转原则,强调我们应该面向接口编程,那什么是接口?接口的作用? 接口如...
    孟婆汤不解渴阅读 836评论 0 3
  • 今天学习下最常见的工厂模式,工厂模式细分下来有三大类: 他们的目标都是一样的:封装对象的创建。但是实现手段和使用场...
    西木柚子阅读 2,140评论 7 28
  • 简单工厂模式(SimpleFactoryPattern) 1.定义 简单工厂模式又叫静态方法模式(工厂类定义了一个...
    luoqiang108阅读 329评论 0 0
  • 设计原则: 要依赖抽象,不要依赖具体类 目录 本文的结构如下: 什么是抽象工厂模式 为什么要用该模式 模式的结构 ...
    w1992wishes阅读 1,102评论 0 6