OC编程之道-创建对象之抽象工厂方法
定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
<AbstractProductA> <AbstractProductB>
<AbstractFactory> createProuductA createProductB
<ConcreteFactory1> createProductA->productA1 createProductB->productB1
<ConcreteFactory2> createProductA->productA2 createProuuctB->productB2
抽象工厂与工厂方法:创建对象而不让客户端知晓返回了什么确切的具体对象
抽象工厂 工厂方法
通过对象组合创建抽象产品 通过类继承创建抽象产品
创建多系列产品 创建一种产品
必须修改父类的接口才能支持新产品 子类化创建者并重载工厂方法以创建新产品
应用: 在touchPainter中为两个公司贴牌 Sierra Corporation和acme Corporation贴Sierra和Acme
tips:软件设计的黄金法则:变动需要抽象
UIView UIButton UIToolBar
brandingFactory brandedView brandedMainButton brandedToolBar
SierraBrandingFactory sierraView sierraMainButton sierraToolBar
AcmeBrandingFactory acmeView acmeButton acmeToolBar
在这种方案下,客户端只需要知道4个实体:brandingFactory、UIView、UIButton、UIToolBar,这样,将来如果需要在需要在其他领域扩展应用程序的品牌活动、可以通过添加新的产品和品牌工厂得以实现,而不影响客户端代码。
实现:
BrandingFactory:NSObject
方法:
+ (BrandingFactory *)factory;//将会返回实际的产品
- (UIView *)brandedView;// return nil;
- (UIButton *)brandedMainButton;// return nil;
- (UIToolBar *)brandedToolBar;//return nil;
+ (BrandingFactory *)factory
{
#if defined (USER_ACME)
return [[[AcmeBrandingFactory alloc]init]autorelease];
#elif defined (USER_SIERRA)
return [[SierraBrandingFactory alloc]init]autorelease];
#else
return nil;
#endif
}
AcmeBrandingFactory:BrandingFactory
并不重载 factory方法,因为他原本用于父类创建具体brandingFactory实例,但是我们无法防止类方法被子类重载。
BrandingFactory以类簇的形式实现,其中一组相关的子类组合在一起,由其超类创建。这种工厂构建过程常见于Cocoa Touch框架的基础类库。
譬如:NSNumber 有一系列共有API,定义了各种类型的数所共有的行为。客户端在使用时无需知道NSNumber实例的具体类型。
类簇是抽象工厂的一种模式,基于抽象工厂模式的思想。它将若干相关的私有具体工厂子类集合到一个公有的抽象超类之下。比如NSNumber本身是一个高度抽象的工厂,而NSCFBoolean和NSCFNumber是具体工厂子类。子类是具体工厂。
创建抽象产品的工厂方法与创建抽象工厂的工厂方法有个不同点:
显然,intValue和boolValue这样的工厂方法,应在具体工厂NSCFNumber与NSCFBoolean中重载以返回实际产品。
其他像numberWithBool:和numberWithInt,这样的工厂方法并不是为了返回产品,而是为了返回产品的工厂,因此他们不应在具体工厂子类中重载。
总结:抽象工厂模式是一种极为常见的设计模式,他是最基本的,因为他可以设计许多类型的对象创建。一系列相关类的好的模式,应该作为一种抽象,不为客户端所见。抽象工厂可以顺畅滴提供这种抽象,而不暴露创建过程中任何不必要的细节或所创建对象的确切类型。
简单工厂,工厂方法,抽象工厂之间的异同
简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
不修改代码的话,是无法扩展的。
工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
在同一等级结构中,支持增加任意产品。
抽象工厂
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。
小结
★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。
区别
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。
原文链接:http://blog.csdn.net/superbeck/article/details/4446177
OC编程之道-创建对象之抽象工厂方法的更多相关文章
- OC编程之道-创建对象之工厂方法
一 何为工厂方法模式?(what) 定义创建对象的接口,让子类决定实例化哪一个类,工厂方法是的一个类的实例化延迟到其子类. 工厂方法创建的对象拥有一组共同的行为,所以往类层次结构中引入新的具体产品并不 ...
- OC编程之道-创建对象之生成器模式
生成器模式也叫建造者模式,一般是用来构造复杂对象的一种模式.client(客户)-director(指导者)-builder(构造者)-product(产品). 生成器模式能帮助构建设计部件与表现的各 ...
- OC编程之道-创建对象之单例模式
一 何为单例singleton模式?(what) 保证一个类只有一个实例,并提供一个访问它的全局访问点. 二 何时使用单例模式?(where) 1类只能有一个实例,而且必须从一个为人熟知的访问点对其访 ...
- OC编程之道-创建对象之原型模式
一 什么是原型模式?(what) 有些对象的创建代价过大或过于复杂,要是可以重建相同的对象并作轻微的改动,事情会容易的多(效率变高).典型的例子是复制组合结构(eg树形结构),从零开始构建一个树型组合 ...
- Java设计模式从精通到入门五 抽象工厂方法模式
定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...
- php设计模式课程---3、为什么会有抽象工厂方法
php设计模式课程---3.为什么会有抽象工厂方法 一.总结 一句话总结: 解决简单工厂方法增加新选择时无法满足面向对象编程中的开闭原则问题 1.什么是面向对象编程中的开闭原则? 应该对类的增加开放, ...
- iOS设计模式解析(二)抽象工厂方法
抽象工厂方法:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 与工厂方法区别: 抽象工厂通过对象组合创建抽象产品.工厂通过类集成创建抽象产品 抽象工厂创建多系列产品.工厂创建一种产 ...
- Android设计模式——抽象工厂方法模式
1.抽象工厂方法模式:为了创建一组或相互依赖的对象提供一个接口,而不需要指定它们是具体类……无语 2.找个代码看看: 抽象工厂类<成员为接口> /** * 抽象工厂 * */ public ...
- 抽象工厂方法模式(Abstract Factory Pattern)
Provide an interface for creating families of related or dependent objects without specifying their ...
随机推荐
- HV000030: No validator could be found for type: java.lang.Integer.
在写接口时,一般去查找在类的Integer属性上加了不属于整型的校验,比如@NotEmpty,@Length等 @JSONField(name = "deviceNum") @No ...
- 【CodeVS 1288】埃及分数
http://codevs.cn/problem/1288/ loli秘制面向高一的搜索,好难啊QAQ 我本来想按照分母从大到小搜,因为这样分母从小到大枚举到的第一个可行方案就是最优方案. 但貌似会T ...
- [转]Android自定义控件三部曲系列完全解析(动画, 绘图, 自定义View)
来源:http://blog.csdn.net/harvic880925/article/details/50995268 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)—— ...
- Android性能优化
Android最佳性能实践 Android最佳性能实践(一)——合理管理内存 Android最佳性能实践(二)——分析内存的使用情况 Android最佳性能实践(三)——高性能编码优化 Android ...
- 页面局部跳转(iframe)
<script type="text/javascript"> function show() { document.getElementById("ff&q ...
- 取消ie浏览器edge浏览器输入框右边的叉和眼睛
在ie高版本浏览器和edge浏览器里type为text和password的input框在输入时右边会出现×和眼睛,如果需要清除,方法如下: 首先在页面头部声明兼容性模式 <meta http-e ...
- ffmpeg 音频转换(amr2mp3)
yasm:http://yasm.tortall.net/Download.html(汇编器,新版本的ffmpeg增加了汇编代码) lame:http://lame.sourceforge.net/d ...
- IDEA中maven搭建Spring+SpringMVC+mybatis项目
一.介绍 使用IDEA搭建maven web项目,整合框架Spring+SpringMVC+mybatis 项目结构图:
- Windows服务已经标记为删除
一般卸载后..刷新一下服务列表就会消失不见..但是也会偶尔碰上一些钉子户.. 这时候其实重启一下机器就可以解决这个问题..会被回收掉..但是在服务器上..可不是随便都能重启的.. 这就到祭出杀手锏的时 ...
- Hive : UDFArgumentTypeException Exactly one argument is expected.
Hive执行时Failed.. 分段执行发现排除一些聚合函数或者内置函数后可以正常执行.. 因为Hive-Sql语句比较长..有很多的case when then 排除后发现是聚合函数的用法问题.. ...