您的位置:首页 > 移动开发 > IOS开发

iOS 21种设计模式之工厂模式

2015-12-04 12:12 423 查看
原创Blog,转载请注明出处

http://blog.csdn.net/hello_hwc?viewmode=list

我的stackoverflow





感谢

感谢《Pro Objective-C Design Pattern for iOS》一书,这个博客系列由很多灵感源自次书。同时,也感谢Wiki以及一些博客博主。每篇文章最后,都会列出参考链接。

这个系列的文章(代码Swift)

工厂

抽象工厂

单例

原型

生成器

适配器

桥接

中介者

观察者

组合

迭代器

访问者

装饰

责任链

模版

策略

命令

享元

代理

备忘录

总结篇:MVC

进阶篇:MVVM

设计模式是为了解决一类问题而出现的,要深刻理解某个模式的应用场景,优点,缺点。千万不要为了使用而实用,那样很可能写出不伦不类的东西。

对于同一种模式,每个人的理解都不同,能解决实际问题才是关键

什么是工厂模式?

工厂是用来生产产品的。在iOS开发中,产品就是类的对象,工厂就是工厂方法。

工厂模式就是定义创建对象的接口,让子类决定实例化哪一个类。这样,类的实例化就推迟到了子类

先看看工厂模式提供的接口,也就是客户端(API使用者)调用的接口

let factory:Factory = ...//获取工厂对象
let product:Product = factory.createProduct()//这里获得到的可能是Product,也可能是Product的子类


可以看到,客户端只需要关注Factory和Product两个类即可,而不需要关注他的子类到底是啥

解决什么问题?

类有一组子类,可以共用一套接口,但是实例化的方式略有差异。用工厂的方式实现,使得客户端(类的调用着)能够专注于接口。而不需要访问具体的实现类。

什么时候使用工厂模式?

编译器无法定义创建对象类

类可以让其子类决定在运行期具体实例化的对象

实现原理

接口定义:工厂类的接口定义可以是类,也可以是协议。

工厂方法定义:

工厂模式的UML图

注意其中红线圈住的部分,那是实际的客户端(API调用着)接触的部分,也就是你设计的接口。在面向对象编程里有个关键的概念:面向接口编程,而不是面向实现编程

对于,客户端来说,只需要接触工厂基类或者协议,得到产品基类就行了。

比如,有一个鞋厂,它告诉我,跟他的代表人(工厂方法)说生产鞋子就行了,今天来的是跑鞋厂的代表,我跟他说生产鞋子,他就给我一双跑鞋。这样,我只需要专注一点:跟我要接触的代表人(工厂方法)说生产鞋子(统一接口),我就能够拿到对应的产品(实例)而我只关心鞋子的通用属性,不关心具体属性。



一个简单例子

Swift的例子采用协议作为抽象基础类,用一个方法来返回不同的对象。

//产品
protocol Shoes{
func logDescription();
}
class RunningShoes:Shoes{
func logDescription() {
NSLog("跑鞋")
}
}
class Sneakers:Shoes{
func logDescription() {
NSLog("板鞋")
}
}
//工厂
protocol Factory{
func createShoes()->Shoes;
}
class RunningShoesFactory:Factory{
func createShoes() -> Shoes {
return RunningShoes()
}
}
class SneakerFactory:Factory{
func createShoes() -> Shoes {
return Sneakers()
}
}
//模拟Runtime的不确定性
class SimulateDynamicFactory{
class func simulateFactory()->Factory{
let randomInt = random()%2
if randomInt == 0{
return RunningShoesFactory()
}else{
return SneakerFactory()
}
}
}


然后,看看客户端代码

let factory:Factory = SimulateDynamicFactory.simulateFactory()
let product = factory.createShoes()
product.logDescription()


可能有同学问了,我为何不直接访问shoes的对象,直接调用构造方法
()
,岂不是更简单直接。面向对象开发还有一个原则对扩展开发,对修改封闭。如果直接使用if else 进行
Shoes()
,那么当有一种新的鞋子出现的时候,客户端将不得不修改大量代码来支持新的鞋子。而使用工厂模式,由于接口始终是一直的,客户端几乎不需要修改什么代码。只需要扩展一类产品,增加一个Factory就可以了。

举个例子,假如我对上文的例子进行扩展,增加一类新的鞋子叫做leoShoes,我需要增加的代码是这样的

class LeoShoes:Shoes{
func logDescription() {
NSLog("扩展鞋子")
}
}
class LeoShoesFactory:Factory{
func createShoes() -> Shoes {
return LeoShoes()
}
}


然后,修改
SimulateDynamicFactory.simulateFactory
方法,看到了吧,客户端代码不用任何修改,假如你是在一个Team负责给别的人开发库,那么库的使用者肯定会谢谢你,否则你每发布一个版本,他都要修改调用

参考链接

WIKI Factory Design Pattern

下一篇

抽象工厂模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息