IOS设计模式浅析之抽象工厂模式(Abstract Factory)
概述
在前面两章中,分别介绍了简单工厂模式和工厂方法模式,我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了“开放-关闭原则”;工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品。但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题。
定义
“提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。”
- 最初的定义出现于《设计模式》(Addison-Wesley,1994)。
结构图

先对上面结构图的几个角色进行说明:
- AbstractFactory:抽象工厂接口,里面应该包含所有产品创建的抽象方法;
- ConcreteFactory1和ConcreteFactory2:具体的工厂,创建具有特定实现的产品对象;
- AbstractProductA和AbstractProductB:抽象产品,它们可能有多种不同的实现方式;
- ProductA1、ProductA2、ProductB1和ProductB2:具体的产品,是抽象产品的具体实现。
从结构图中可以看到,抽象工厂方法最大的好处是能够很方便的变换产品系列(例如id<AbstractFactory> factory =[ [ConcreteFactory1 alloc] init],只需要将ConcreteFactory1换成ConcreteFactory2,就可以创建ProductA2和ProductB2)。另外,抽象工厂方法让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中(例如id<AbstractProductA> product = [factory createProductA],客户端根本不知道具体的类名是ProductA1还是ProductA2)。
但是,抽象工厂方法也是存在缺点的,比如说现在我们要增加一个新的产品,首先,我们需要增加三个类:AbstractProductC、ProductC1、ProductC2;另外,我们还需要更改三个类:AbstractFactory、ConcreteFactory1、ConcreteFactory2,这样,很明显是违背“开放-关闭原则”。这也是可以理解的,没有任何一个设计模式是完美没有瑕疵的,这就好比世界上没有打不败的武功一样。我们可以做的就是在实际的需求中,尽可能的将变化点进行隔离,以达到变化发生的时候,对整个系统的影响最小,变化所带来的变更和成本最低。
示例
还是继续简单工厂模式和工厂方法模式的应用场景,这里将场景稍微改变一下:我们知道,绘制统计图形的方案有多种,我们既可以使用OWC来绘制统计图形,也可以使用HTML 5来绘制统计图形,或者其他的一些第三方插件来进行绘图,等等。这里我们用OWC和HTML 5绘制统计图形来说明抽象工厂模式(注意:示例和场景只是为了说明设计模式的思想,并不是说实际开发中我们就会这么使用)。先来看看新应用场景使用抽象工厂模式实现的结构图:

根据结构图,我们来看看部分源码(完整代码在后面会提供下载)。
AbstractLine.h:
@protocol AbstractLine <NSObject> - (void)drawLine;
AbstractPie.h:
@protocol AbstractPie <NSObject> - (void)drawPie;
AbstractFactory.h:
@protocol AbstractFactory <NSObject> - (id<AbstractLine>)createLine;
- (id<AbstractPie>)createPie;
客户端调用代码:
id<AbstractFactory> factory = [[[HTML5Factoryalloc] init] autorelease];
// id<AbstractFactory> factory = [[[OWCFactory alloc] init] autorelease];
id<AbstractLine> line = [factory createLine];
id<AbstractPie> pie = [factory createPie]; [line drawLine];
[pie drawPie];
从调用代码我们可以看到抽象工厂的两个优点:
- 能够很方便的变换产品系列;
- 具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
抽象工厂模式的缺点我们前面也分析了:在新加产品的需求下,违背开放-封闭原则。通过优缺点的比较,我们可以在如下场景下使用抽象工厂模式:功能模块已经非常成熟,基本上不需要太多修改,但是有可能会替换掉实现这些功能模块的类的那种情况。比如说数据库链接,所有的JDBC功能模块几乎一样,只不过种类有所不同,有些是SQL-Server,有些是Oracle,那么这时候用抽象工厂来实现,面对更换数据库的情况,就比较方便了。
【小思考】:从上面的客户端调用代码看到,如果有多处变换产品系列的地方,我们需要每处都进行修改,这样的话,实际上也没有达到我们的效果:应对变化,尽可能少的修改代码。那么该怎样处理这种情况呢?解决方案可以参看工厂方法模式中的思考小节。
抽象工厂模式&建造者模式
抽象工厂模式和建造者模式都属于创建型模式,它们在对象创建方面存在许多相似之处。但是,两者也存在较大的区别,具体如下:
|
建造者模式 |
抽象工厂模式 |
|
构建复杂对象 |
构建简单或复杂对象 |
|
以多个步骤构建对象 |
以单一步骤构建对象 |
|
以多种方式构建对象 |
以单一方式构建对象 |
|
在构建过程的最后一步返回产品 |
立刻返回产品 |
|
专注一个特定产品 |
强调一套产品 |
抽象工厂模式&工厂方法模式
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个;工厂方法模式中工厂类一般只有一个方法,创建一种产品;抽象工厂模式中工厂类一般有多个方法,创建一系列产品。
可以这么来理解:工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广。
IOS设计模式浅析之抽象工厂模式(Abstract Factory)的更多相关文章
- 设计模式学习心得<抽象工厂模式 Abstract Factory>
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
- Net设计模式实例之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式简介(Bref Introduction) 抽象工厂模式(Abstract Factory Pattern),提供一个创建一系列相关或者相互依赖对象的接口,而无需制定他们的具体类.优点 ...
- 《JAVA设计模式》之抽象工厂模式(Abstract Factory)
场景问题 举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU.硬盘.内存.主板.电源.机箱等.为讨论使用简单点,只考虑选择CPU和主板的问题. 事实上,在选择 ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...
- 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释
抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...
- 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...
- 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...
随机推荐
- mysql-connector-java-6日期存储时差的问题解决方法
在my.ini文件中的[mysqld]下面加入 default-time_zone = '+8:00' 重启mysql 修改driver连接路径 这样日期保存到mysql就是正确的了,但是mysql- ...
- ajax回调中window.open弹出的窗口会被浏览器拦截的解决方法
存在问题:处理页面ajax请求过程中,异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法 来实现,最终都被浏览器拦截了.不会跳到对应的页面,如下 原因:浏览器之所以拦截 ...
- Coherence对象压缩以及对象大小计算
1.通过util.zip带的gzip压缩程序 Coherence对象压缩程序如下 package coherencetest; import com.tangosol.net.CacheFactor ...
- Texygen文本生成,交大计算机系14级的朱耀明
文本生成哪家强?上交大提出基准测试新平台 Texygen 2018-02-12 13:11测评 新智元报道 来源:arxiv 编译:Marvin [新智元导读]上海交通大学.伦敦大学学院朱耀明, 卢思 ...
- 开发板tftp:timeout问题
想要从PC上面tftp文件的时候遇到了tftp:timeout的问题: >: tftp -gr gprsapp 192.168.1.38tftp: timeout 检查了网络,可以ping的通P ...
- Java程序员到架构师的推荐阅读书籍
作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...
- opengl中VAO,VBO,IBO用法小结(zz) 【转】
http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...
- Vue组件基础知识总结
组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树. 那么什么是组件呢?组件可以扩展HTML元素,封装 ...
- C# 操作mongodb 简单实例
本实例主要简单的查询,新增,修改和删除操作,完整代码如下: using System; using System.Collections.Generic; using System.Text; usi ...
- [转]Nginx调用远程php-fpm
Nginx调用远程php-fpm 前后端分离的网站,要在异地部署多套网页的时候,这种nginx配置调用远程php-fpm的方式,不错.可以提高网页的相应速度. 原文: https://www.cnbl ...