iOS 21种设计模式之原型模式Prototype

原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow

感谢

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

这个设计模式系列的文章

对象创建模式

  • 工厂
  • 抽象工厂
  • 单例
  • 原型
  • 生成器
  • 适配器
  • 桥接
  • 中介者
  • 观察者
  • 组合
  • 迭代器
  • 访问者
  • 装饰
  • 责任链
  • 模版
  • 策略
  • 命令
  • 享元
  • 代理
  • 备忘录
  • 总结篇:MVC
  • 进阶篇:MVVM

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

何为原型?

原型可以理解为模版,在创建新的对象的时候,按照模板的方式来复制。这样避免了重新创造轮子。
简单理解就是:创建第一个模板对象,然后通过复制模板来创建新的对象,还记得UITableviewCell的Deque方法吗?这其实就是一个“原型”,

解决什么问题?

  • 解决了每次创建新的对象,都需要alloc init,这样就造成了代码要直接访问具体的类,也就增加了代码的耦合度。
  • 避免创建工厂类的子类(例如抽象工厂模式)
  • 通过copy能够保存对象当时的状态

什么时候使用原型模式?

  • 需要创建的对象不依赖于具体的类型以及创建方式
  • 具体实例化的对象类型是在运行期决定的
  • 不同类型之间的差异紧紧是状态的组合
  • 类型创建不容易,例如类型有复杂的嵌套

原型模式的UML图

iOS 21种设计模式之原型模式Prototype_第1张图片

实现原理

  • Swift/Objective C并不支持抽象基或者抽象方法。但是可以使用协议类似定义一个抽象的“基类”,定义通用的属性,方法,以及复制方法。
  • 具体的类负责实现复制方法,以及公用的方法。
  • 通过抽象基类的接口创建对象

Swift 2.1例子

例子是要存储复杂的嵌套数据结构

假设我有一个绘图类LeoDrawer,那么这个Drawer必然要保存每一步后操作的结果,这样我能够进行redo和undo(可以用NSUndoManager,这里只是举例)。类似这种快照就是原型模式的典型场景
定义原型

protocol Shape{
    var location:CGPoint{get set}
    func draw()
    func clone()->Shape
}

具体的类

class RoundShape: Shape { var location:CGPoint init(location:CGPoint){ self.location = location } func draw() { } func clone() -> Shape { let shape = RoundShape(location: self.location) return shape } } class RectShape:Shape { var location:CGPoint init(location:CGPoint){ self.location = location } func draw() { } func clone() -> Shape { let shape = RectShape(location: self.location) return shape } } 

客户端

class LeoDrawer{
    var shapes:[Shape]?
}
let drawer = LeoDrawer()
drawer.shapes = [RoundShape(location: CGPointMake(1, 1)),RectShape(location: CGPointMake(10, 10))]

let shapesSnapshot = drawer.shapes?.map({ (shape) -> Shape in return shape.clone() }) 

优点

在扩展的时候,子类遵循原型的协议,很容易的扩展。并且,客户端代码不需要任何修改

参考链接

  • WIKI Prototype Design Pattern

你可能感兴趣的:(设计模式,ios,prototype,原型)