009-工厂模式(简单工厂模式)

顾名思义,就是一种很简单的工厂模式。在业务比较简单的情况下使用。


简单工厂模式类图如下:

上述类图中有如下三种角色:

工厂类角色(Creator):这是本模式的核心,含有一定的业务逻辑和判断逻辑,在Java中往往由一个具体类实现。工厂类依赖于具体产品。

抽象产品角色(Product):一般是具体产品继承的父类或者实现的接口,在Java中由接口或者抽象类实现。

具体产品角色(ConcreteProduct):工厂类所创建的对象就是此角色的实例,在Java中由一个具体类来实现。具体产品继承于抽象产品。


功能:工厂是用来造东西的。在Java里面,通常情况下用它来造接口,但是也可以造抽象类,甚至是一个具体类实例。可以利用简单工厂来创建接口、抽象类或者普通类的实例。


静态工厂:当使用简单工厂的时候,通常不用创建简单工厂类的类实例,因为没有必要,因此可以把简单工厂类实现成一个工具类,直接使用静态方法就可以。也就是说简单工厂的方法通常都是静态的,所以也被肠胃静态工厂,如果要防止客户端误创建简单工厂类实例,可以把构造方法私有化。


万能工厂:一个简单工厂可以包含很多用来构造东西的方法,这些方法可以创造不同的接口、抽象类或者类实例,一个简单工厂,理论上可以构造任何东西,所以又被称为万能工厂。在工厂里可以有一个或者多个创造方法。


范围:理论上简单工厂什么都能创造。但是对于简单工程可创建对象的范围来说,通常建议不要太大,建议将其控制在一个独立的组件级别或者一个模块级别,否则这个简单工厂会职责不明,有点大杂烩的感觉。


命名建议:类名建议写成“模块名称+Factory”,比如用户模块的工厂为 UserFactory。方法名通常为 get+接口名称,或者是 create+接口名称,比如有个接口名为User,那么方法名通常为 getUser或者createUser。还有一些人习惯为  new+接口名称,比如newUser,通常不建议这种方式,因为new在Java中代表特定的含义,而且通过简单工厂来获取对象的实例,并不是每次都new,因为使用new可能会造成误会错觉。



简单工厂的思想源于Java中的接口,Java中接口是一种特殊的抽象类,跟一般的抽象类相比,接口中所有的方法都是抽象的,接口中所有的属性通常都是常量,也就是说接口里只有定义没有实现。

(1)接口用来干什么

通常用接口来定义实现类的外观,也就是定义实现类的行为,也可以说用来约束实现类必须实现的行为。但是通常实现类除了实现接口定义的方法外,还可以根据需要实现一些其它的功能,也就是说实现类的功能包含但是不仅限于接口约束的功能。通过使用接口可以让不相关的类实现相同的行为,而不需要考虑这些类之间的层次,接口就是实现类对外的外观。


(2)接口的思想

根据接口的作用和用途,简单来说,接口的思想就是封装隔离。一般的封装是封装数据,接口的封装是封装行为,也可以说是职责。隔离指的是外部调用和内部实现的隔离,外部调用只能通过接口调用,而不知道内部具体实现。


(3)使用接口的好处

由于外部调用和内部实现被隔离了,那么只要接口本身不变,内部实现的变化就不会影响到外部调用的代码,从而使得系统更灵活,更具有扩展性和可维护行,也就是常说的接口是系统可插拔性的保证。


(4)接口和抽象类的选择

接口是一种特殊的抽象类,在开发中如何选择,一般遵循两点:

》优先选用接口

》如果既要定义子类的行为,又要为子类提供功公共的功能,要选择抽象类



除了客户端调用代码,简单工厂模式大致可以分为三种代码,一是定义客户端所需要功能的接口,二是工厂类,用来选择合适的实现类创建接口对象,三是各种实现类。


接下来举个简单的例子,可以把运动员看成一个总的接口,分别有篮球运动员和足球运动员两个实现类,要想成为运动员必须在联盟注册,球员联盟可以看成一个工厂。

首先看一下运动员的接口代码:

可以看到接口中只定义了一个注册方法,传入了一个字符串,注册方法就是所有运动员都必须有的行为。


接下来看足球运动员和篮球运动员两个具体实现类:



可以看到两个实现类也非常简单,在实现方法中只是打印了身份和传入的字符串。


接下来看一下工厂类的具体内容:

工厂类定义了一个create接口对象的方法,根据传入的条件判断使用哪个实现类创建实例,内容也很简单。


上面四个类构成了工厂模式的全部要素。使用的时候分两步,首先通过工厂类根据传入的条件返回一个运动员实例,然后运行注册方法就可以看到成功创建了实例,调用代码如下:

运行结果如下:

这样可以让工厂对创建实例而不再由具体的类去创建。从调用代码看,我们也不关心具体的实现是什么,也不知道如何具体实现。事实上简单工厂帮助我们真正开始面向接口编程,以前的做法只是接口多态的功能,最重要的封装隔离性并没有体现出来。让调用者不知道内部具体实现。


上面的代码虽然仅仅是把new操作放到了工厂方法里面,但是却真正实现了封装和隔离,让调用代码无法了解具体的实现内容,而工厂和实现封装在一起是没有关系的。虽然仅仅是new操作的位置变了,却发生了质的变化。


上面的简单工厂也有不足,如果接口和实现类不变,新增了一个实现类,那么工厂类的方法必须做出修改,在一定程度上增加了维护成本。要想做到增加了实现类而不修改任何代码,一个简单的思路是利用配置文件和反射来实现动态新增创建,新建一个配置类simple.properties,内容如下:

可以看到定义了传入条件和具体实现类的键值对。


接下来我们要对工厂类的创建方法做出修改:

可以看到方法根据传入的条件动态获取配置文件中的类路径,然后利用反射创建对应实例,这样新增实现类只需要增加一行配置即可,不需要修改任何代码。


首先不新增实现类,运行前面的客户端代码,

可以看到结果正确。然后新增一个实现类,

然后新增一行配置:

修改客户端代码并运行:


可以看到实现类增加实现类而无需修改代码。



简单工厂模式的总结:

优点

(1)实现了组件封装,让组件外部真正面向接口编程

(2)实现了客户端和具体实现类的真正解耦

缺点

(1)根据参数决定创建的具体实例,势必让客户端理解参数所代表的含义,也暴露了部分内部实现。

(2)不方便通过工厂的子类改变创建接口的方法行为,不过一般也不需要。


简单工厂的本质就是,选择实现,屏蔽具体类。


使用建议:灵活传递选择条件,可以使用配置文件,也可以读取运行期间内存的某个值。

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

推荐阅读更多精彩内容