定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
<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 ...
随机推荐
-
UWP/Win10新特性系列—UserConsentVerifier
在UWP开发中,微软提供了新的用户许可验证方式-指纹(生物识别).Pin.密码验证.在爆料的新型Win10 Mobile移动设备中,会增加虹膜识别等先进的用户身份识别技术,微软现在统一了身份验证的AP ...
-
eclipse错误:Unable to read workbench state. Workbench UI layout will be reset.XML document structures
Unable to read workbench state. Workbench UI layout will be reset.XML document structures must start ...
-
Python学习总结3:元组、列表的操作汇总
参考博客:http://www.cnblogs.com/QG-whz/p/4782809.html 1. 是否可变 元组:用()或tuple函数定义,不可变(元素的值以及整个元组): 列表:用 [] ...
-
typedef void (*funcptr)(void)
定义一个函数指针类型.比如你有三个函数:void hello(void) { printf("你好!"); }void bye(void) { printf("再见!&q ...
-
ios 监听app从后台恢复到前台
正常情况下,在AppDelegate中实现下面两个方法,能够监听从后台恢复到前台 [cpp] - (void)applicationDidEnterBackground:(UIApplication ...
-
推荐几个可以与PhoneGap很好搭配的UI框架
- xui.js:可以被视作是jquery在phonegap上的替代品,挺好用的- jq.mobi:同上,不过体积比xui.js要大,一般还是用xui.js- jq.ui:jq.mobi配套的UI框架 ...
-
vlc_input buffer管理 &; 时钟同步(转)
vlc_input buffer管理 & 时钟同步 一.背景1.当播放网络视频流时(比如udp视频流),发送方(编码)和接收方(解码)是并行操作的,如果发送太慢(或因为网络原因出现延迟)的话, ...
-
angular在ie8下的一个bug
昨天拿项目在ie8下测试,发现不少bug,其中有一个bug让我很不解,报了一个thead开头的bug,因为已经切回到linux下了,我就不报具体是什么bug了,鼓捣了半天,发现引用angular的应用 ...
-
Chapter 15_3 使用环境
创建模块的基本方法的缺点在于,忘记使用local,很容易就污染全局空间. “函数环境”是一种有趣的技术,它能够解决上面的问题.就是让模块的主程序块独占一个环境. 这样不仅它的所有函数可以共享这个tab ...
-
vue路由跳转时判断用户是否登录功能
通过判断该用户是否登录过,如果没有登录则跳转到login登录路由,如果登录则正常跳转. 一丶首先在用户登录前后分别给出一个状态来标识此用户是否登录(建议用vuex): 简单用vuex表示一下,不会可以 ...