《重构与模式》 Swift 版之创建方法

作者:Natasha The Robot,原文链接,原文日期:2016-05-27
译者:Crystal Sun;校对:Cee;定稿:Channe

正如上个月在几个会议上我所讲的那样《重构与模式》 这本书被多次提及,特别是在我喜欢的研讨会上。最终我还是读了一小部分(至少是在 WWDC 大会发布后的疯狂情绪高涨之前),并且我希望能够通过将书中的模式(pattern)记录下来,以供将来参考。我还发现,通过把书中的 Java 代码翻译成 Swift,我能更好地记住这些知识点。

第一个模式就是创建方法

重构之前

先假设你有一个 model,比如是借款,并且里面有一些不同的初始化构造器(initializer)。在这个例子中,每个初始化构造器都有存在的理由——每个初始化构造器代表了对应了不同的借款类型:

struct Loan {
    let commitment: NSDecimalNumber
    let riskRating: Float
    let maturity: Int
    let expiry: NSDate?
    let capitalStrategy: String?
    let outstanding: NSDecimalNumber?
    
    init(commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate?, capitalStrategy: String?, outstanding: NSDecimalNumber?) {
        self.commitment = commitment
        self.riskRating = riskRating
        self.maturity = maturity
        self.expiry = expiry
        self.capitalStrategy = capitalStrategy
        self.outstanding = outstanding
    }
    
    init(commitment: NSDecimalNumber, riskRating: Float, maturity: Int) {
        self.init(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: nil, capitalStrategy: nil, outstanding: nil)
    }
    
    init(commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) {
        self.init(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: nil, outstanding: nil)
    }
    
    init(commitment: NSDecimalNumber, outstanding: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) {
        self.init(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: nil, outstanding: outstanding)
    }
    
    init(capitalStrategy: String, commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) {
        self.init(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: capitalStrategy, outstanding: nil)
    }
    
    init(capitalStrategy: String, commitment: NSDecimalNumber, outstanding: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) {
        self.init(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: capitalStrategy, outstanding: outstanding)
    }
}

看看这代码,你会完全没有思路(除非你知道所有的借贷类型),不知道该用哪个初始化构造器。当然了,一些刚刚接触这代码的新人可能还对项目的业务不是很清楚,所以他们可能会用错初始化构造器,甚至会对这些初始化构造器的作用意图感到疑惑。

是时候来重构了!

重构之后

用创建方法(Creator Method)重构后的代码如下:

struct Loan {
    let commitment: NSDecimalNumber
    let riskRating: Float
    let maturity: Int
    let expiry: NSDate?
    let capitalStrategy: String?
    let outstanding: NSDecimalNumber?
    
     // 原来的初始化构造器(initializer)现在可以是私有的
    private init(commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate?, capitalStrategy: String?, outstanding: NSDecimalNumber?) {
        self.commitment = commitment
        self.riskRating = riskRating
        self.maturity = maturity
        self.expiry = expiry
        self.capitalStrategy = capitalStrategy
        self.outstanding = outstanding
    }
    
    static func createTermLoan(commitment: NSDecimalNumber, riskRating: Float, maturity: Int) -> Loan {
        return Loan(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: nil, capitalStrategy: nil, outstanding: nil)
    }
    
    static func createTermLoan(capitalStrategy: String, commitment: NSDecimalNumber, outstanding: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) -> Loan {
        return Loan(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: capitalStrategy, outstanding: outstanding)
    }
    
    static func createRevolverLoan(commitment: NSDecimalNumber, outstanding: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) -> Loan {
        return Loan(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: nil, outstanding: outstanding)
    }
    
    static func createRevolverLoan(capitalStrategy: String, commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) -> Loan {
        return Loan(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: capitalStrategy, outstanding: nil)
    }
    
    static func createRCTL(commitment: NSDecimalNumber, riskRating: Float, maturity: Int, expiry: NSDate) -> Loan {
        return Loan(commitment: commitment, riskRating: riskRating, maturity: maturity, expiry: expiry, capitalStrategy: nil, outstanding: nil)
    }
}

注意到重构后的代码多么漂亮了吗!当你初始化一个借贷的 model 时,你知道它的作用了。

虽然我一般不会在类里使用这么多的初始化构造器,而且有时在 Swift 中可以根据不同的实际情况使用更好的方法来解决问题(比如使用枚举)。不过如果我想让我的代码更具可读性、变得更加简洁,我一定会考虑重构成这种模式。

本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问 http://swift.gg

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,222评论 4 61
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,613评论 25 709
  • 专题 青春散场 目录 上一章【连载】青春散场 第四章 报到入学 (4) 青春就像是一个大大的笑脸和一个大大的哭脸,...
    圆琛儿阅读 1,690评论 0 4
  • 2q全文595字,19幅图片,建议阅读2分钟。 十一黄金周,天安门、故宫、王府井、西单、南锣鼓巷、颐和园、雍和宫等...
    小七君阅读 3,385评论 0 6
  • 接龙客栈纯文字协会简书接龙客栈纯文字协会 文丨蔷薇下的阳光 历时半个月的接龙客栈的七夕接龙马上接近尾声了,明天会出...
    蔷薇下的阳光阅读 3,868评论 0 6