美文网首页iOS开发iOS学习征服iOS
设计模式笔记及Swift上的实现之三『FACTORY METHO

设计模式笔记及Swift上的实现之三『FACTORY METHO

作者: sim_cai | 来源:发表于2017-01-22 23:02 被阅读49次

    工厂方法可能是我们最常见的模式之一。

    意图

    定义一个用来创建子对象的接口,让子类决定实例化哪一个类。

    动机

    举个例子,我们做一个 App,这个 App 中有各种样式的弹开框。我们可能会定义许多对应样式的弹开的子类,可以用户层其实并不关心你哪个样式的弹框需要对应哪一个子类。用户层只关心创建一个弹框,显示弹框。

    而工厂方法模式正好给我们提供了这类型问题的解决方案。

    适应性

    • 当一个类不知道它所必须创建的对象的类的时候。
    • 一个类希望由他的子类来指定他所创建的对象的时候。
    • 当类将创建对象的职责委托给多个子类中的某一个,并且你希望将子类是代理者这一信息的局部化。

    结构

    工厂方法结构.png

    参与者

    • Product

    —— 定义工厂方法所创建的对象的接口

    • ConcreteProduct

    —— 实现Product接口

    • Creator

    —— 声明工厂方法,该方法返回一个 Product 类型的对象。Creator 也可以定义一个工厂方法的缺省实现,它返回一个缺省的 ConcreteProduct 对象。
    —— 可以调用工厂方法以创建一个 Product 对象。

    • ConcreteCreator

    —— 重定义工厂方法以返回一个 ConcreteProduct 实例。

    协作

    • Creator 依赖于它的子类来定义工厂方法,所以它返回一个适当的 ConcreteProduct 实例。

    效果

    缺点

    工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的 ConcreteProduct 对象,就不得不创建 Creator 的子类。

    优点

    • 为子类提供hook
    • 连接平行的类层数

    实现

    主要有两种不同情况

    • Creator 类是一个抽象类并且不提供它所声明的工厂方法的实现。
    • Creator 是一个具体的类而且为工厂方法提供一个缺省的实现。

    参数化工厂方法

    使得工厂方法可以创建多种产品。工厂方法采样一个标识要创建的对象种类的参数。

    使用模板

    我们可以通过模板(泛型)来避免为了创建一个特定的 ConcreteProduct 对象,而不创建 Creator 的子类的问题。

    代码示例

    最后还是更具惯例来段代码示例,示例中使用的是参数化的工厂方法。我这边还是以创建弹框为例子。

    弹框样式

    我们先明确一下需求,我们需要通过一个工厂方法来创建 3 种样式的弹框。
    分别是:

    • done 只有一个确定按钮的弹框
    • comfirm 有两个按钮(确定和取消)
    • share 常见的分享用的弹框
    enum AlertViewType {
        case done, comfirm, share
    }
    

    创建 Product 和 Creator

    这里我们定义了一个 AlertView 它及时 Product 也是 Creator
    它定义了弹框对应的接口 show,也定义了工厂方法 createAlertView

    class AlertView {
        
        static func createAlertView(with type: AlertViewType) -> AlertView {
            
            switch type {
            case .done:
                return DoneAlertView()
                
            case .comfirm:
                return ComfirmAlertView()
                
            case .share:
                return ShareAlertView()
     
            }
            
        }
        
        func show() {
            
        }
        
    }
    

    定义 ConcreteProduct

    这里我定义了 3 种类型的产品

    • DoneAlertView 只有一个确定按钮的弹框
    • ComfirmAlertView 有两个按钮(确定和取消)
    • ShareAlertView 常见的分享用的弹框

    并各自实现了它们的 show 接口。

    
    class DoneAlertView: AlertView {
        
        override func show() {
            print("完成确认的弹框样式。")
        }
        
    }
    
    class ComfirmAlertView: AlertView {
        
        override func show() {
            print("有两个按钮(确定和取消)的弹框样式。")
        }
        
    }
    
    class ShareAlertView: AlertView {
        
        override func show() {
            print("常见的分享用的弹框的弹框样式。")
        }
        
    }
    
    

    用户使用

    我们通过工厂方法来创建对象,具体创建什么对象有参数决定。创建出来的对象调用 show 接口,执行它所对应的对象的操作。

    let doneAlert = AlertView.createAlertView(with: .done)
    doneAlert.show()
    
    let comfirmAlert = AlertView.createAlertView(with: .comfirm)
    comfirmAlert.show()
    
    let shareAlert = AlertView.createAlertView(with: .share)
    shareAlert.show()
    

    打印信息

    完成确认的弹框样式。
    有两个按钮(确定和取消)的弹框样式。
    常见的分享用的弹框的弹框样式。
    

    总结

    工厂方法可以让用户使用接口时不需要关心他真实对应的哪一个类,不需要关心平行子类的区别。

    附:Playground 代码

    欢迎讨论、批评、指错。

    相关文章

      网友评论

        本文标题:设计模式笔记及Swift上的实现之三『FACTORY METHO

        本文链接:https://www.haomeiwen.com/subject/qbnobttx.html