zoukankan      html  css  js  c++  java
  • 21种设计模式

    这个设计模式系列的文章

    对象创建模式 

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

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


    何为原型?

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


    解决什么问题?

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

    什么时候使用原型模式?

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

    原型模式的UML图


    实现原理

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

    Swift 2.1例子

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

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

    protocol Shape{
        var location:CGPoint{get set}
        func draw()
        func clone()->Shape
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    具体的类

    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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    客户端

    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()
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    优点

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

    提高技能如同提升自信心。
  • 相关阅读:
    .Net 框架培训
    根据 XSD生成 Data Contract之怪现象
    WCF performance
    IIS7 performance
    【原】[SQL function] SQL Server Split Function
    【原】[Data.Common.Format] 格式化传入的float(浮点型)字符串
    【原】[Crystal Reports] 当前一条记录与前一条记录比较
    【转】C#中处理XML文档的方法
    【原】Crystal Reports水晶报表 格式化传入的float字符串
    【转】[ASP] 用 ASP 创建 GUID
  • 原文地址:https://www.cnblogs.com/chims-liu-touch/p/6045229.html
Copyright © 2011-2022 走看看