闲话设计模式之抽象工厂模式

本文以对话模式来进行,为了完成对话,我决定将自己有丝分裂,就“风海”和“铜锣”吧。

风海: 铜锣老弟,听说你最近的文件管理器项目进展很顺利啊,来,给我看看做到哪里了?嗯,这个按钮感觉不够炫酷啊,来,加个荧光特效,再描个边,中间再塞个小图标……

铜锣: 去去,风海老兄,就算你要改按钮也要遵守基本法啊,你没看整个产品的格调是“简约”么?

风海: emm……好吧。不过像我这种追求酷炫的,对你这个界面不太感冒啊。来来来,咱们来聊聊,假设我是个产品经理,要求你的界面既支持简约,又支持酷炫,你该怎么做。

铜锣: 得亏我是个人开发者,不用理会你这个需求。不过如果你是公司的产品经理,那我就不得不听命了。确实,对于一些产品来说,换肤是个很适合个性化人群的需求,比如PC端的QQ。

风海: 对啊,换肤多炫酷啊,QQ可以换肤,还有各种PC端的音乐播放器,哦,还有输入法。

铜锣: 嗯,每个产品都有自己的视觉架构,比如说QQ,就有好友栏,对话框,功能按钮栏等。音乐播放器有音波展示区,按钮区。如果要做换肤,就要定义好产品的视觉架构,然后去做抽象。

风海: 听得我似懂非懂,那我问你,假如你这个按钮要做换肤,你具体该怎么做嘛……哦等等,你这个按钮一变酷,标题栏还是老土风格,不行,一起换了。

铜锣: 你看你看,光换一个按钮解决不了问题吧,你又提到了标题栏,所以这是成套的设计。我就从你说的这两个做起,你要按钮和标题栏的视觉效果是动态可变化的对吧。那我设计一个类满足你:

class UI_AbstractFactory {
    func createButton() -> Button? { nil }
    func createTopBar() -> TopBar? { nil }
}

风海: 我看到了Factory,那说明你要使用工厂模式嘛,我们之前已经聊过了这个模式了。

铜锣: 你的记性不错,确实工厂模式我们已经聊过了,这个也确实是工厂模式,不过还是可以聊一聊的,因为它是工厂模式的衍生版本:抽象工厂模式。

风海: 怪不得前面还有个Abstract。那么抽象工厂模式和普通的工厂模式有什么不同?

铜锣: 在普通工厂模式里,工厂负责创建接口使用者需要的对象,但是接口使用者不需要关心具体的对象类型,只需要关心已知的返回对象类型和接口即可。

比如当我使用一个视图工厂时,该工厂可以给我提供必要的视图,我只要用来展示就行了,我不需要关心具体视图是查看图片视图,还是播放视频视图。

抽象工厂模式也是工厂模式,但是多出了以下几点不同:

  1. 存在一个抽象工厂类型,该类型是抽象的类型定义,它定义了具体的生产接口,而不负责具体的生产任务。
  2. 具体的生产任务交给具体的工厂类型完成,具体的工厂类型明确定义了生产接口具体该生产什么类型的生产对象。

风海: 哦,我明白了,也就是说,在你举的例子里,UI_AbstractFactory是一个抽象工厂,我就叫他“UI工厂”好了,这个UI工厂是抽象的,那么具体的生产任务会交给具体的工厂来完成,对吧。

铜锣: 对,你这个UI工厂起名起的不错嘛。我在这里创建了一个UI工厂,它负责提供各种各样的UI接口,比如按钮啊,标题栏啊。但是具体该怎么实现这些接口,就交给具体的工厂来完成,比如我现在就定义了一个“极简UI工厂”。

class SimplifyUI_Factory: UI_AbstractFactory {
    func createButton() -> Button? {
        return SimplifyButton()
    }
    
    func createTopBar() -> TopBar? {
        return SimplifyTopBar()
    }
}

风海: 我懂了!你把工厂给“抽象”了,目的就是为了灵活配置工厂类型,比如你现在实现了一个“极简UI工厂”,那么为了满足我的需求,你可以再实现一个“炫酷UI工厂”。

铜锣: 呵,可不是为了满足你的需求吗,不然我还写什么抽象工厂模式,毕竟程序员没事不会给自己瞎折腾,设计模式就是为了解决需求的,没有需求就不要凭空写设计模式,为设计模式而设计模式是设计模式的大忌……

风海: 别,你把我绕晕了。你还是赶紧给我写一个酷炫UI工厂吧。

铜锣: 好嘞。

class CoolUI_Factory: UI_AbstractFactory {
    func createButton() -> Button? {
        return CoolButton()
    }
    
    func createTopBar() -> TopBar? {
        return CoolTopBar()
    }
}

你想要用酷炫的工厂进行生产,那么代码如下

var factory: UI_AbstractFactory?
...
factory = CoolUI_Factory()
...

let button = factory.createButton()
...
let topbar = factory.createTopBar()
...

风海: 嗯,酷炫UI工厂果然生产了酷炫的标题和顶栏。所谓龙生龙凤生凤,不同的工厂负责生产不同的道具。各司其职,很不错呢,最关键的是,如果想要切换可以批量而不是挨个切换。

铜锣: 对,没错,这就是抽象工厂模式的核心价值。

我们且参看抽象工厂模式在维基百科的定义吧。

抽象工厂模式(英语:Abstract factory pattern)是一种软件开发设计模式。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。客户端程序不需要知道(或关心)它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。

风海: 嗯,我看到网上还把工厂模式分为三类:简单工厂模式,普通工厂模式和抽象工厂模式。而我们好像就讨论了两类,这是为什么?

铜锣: 是的,我们之前讨论过工厂模式的例子。事实上简单工厂模式和普通工厂模式的差别比较小,可以合在一起讲,它们的区别是简单工厂模式里,工厂直接负责产品的生产,而到普通工厂模式里,工厂是个抽象类,具体的生产行为交给了具体的工厂。到了抽象工厂模式里,工厂生产的对象不止一个,而是多个。

风海: 这么看来,抽象工厂模式真的很适合解决换肤问题呢,还有做PC软件时,MacWin风格的切换这类。

铜锣:对,只要涉及到“批量的接口替换”的需求。都可以考察一下是否需要抽象工厂模式呢。

风海: 很棒,今天是周六了,我们去好好吃一顿吧。周末愉快。

铜锣: 周末愉快,走起。

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

推荐阅读更多精彩内容