《重构与模式》Swift 版之参数对象

《重构与模式》Swift 版之参数对象,第1张

概述作者:Natasha The Robot,原文链接,原文日期:2016-05-28 译者:Channe;校对:Cee;定稿:千叶知风 我最近在读《重构与模式》 。昨天(译注:原文日期的昨天),在我写描述了一个拥有多个参数对象的《创建方法》时,想到了@modocache关于iOS API 设计中的 Swift 模式超棒的演讲,尤其是关于参数对象部分。我第一次看的时候获益匪浅,因此我希望记录下来。

作者:Natasha The Robot,原文链接,原文日期:2016-05-28
译者:Channe;校对:Cee;定稿:千叶知风

我最近在读《重构与模式》 。昨天(译注:原文日期的昨天),在我写描述了一个拥有多个参数的对象的《创建方法》时,想到了@modocache关于iOS API 设计中的 Swift 模式超棒的演讲,尤其是关于参数对象部分。我第一次看的时候获益匪浅,因此我希望记录下来。

问题

假设你在写一个 BananaUIKit 库,包含了一个简单的 BananaAlertVIEw:

最开始的代码可能想这样:

public class BananaAlertVIEw {        public static func show(        withTitle Title: String,message: String,dismissbuttonText: String)    {        // 具体实现    }}

这个实现很好,直到一位使用这个框架的用户请求能够将 BananaAlertVIEw 的颜色由棕色换为黄色...

为了确保更改这个框架不影响其他用户,我们使用 Swift 的默认参数:

public class BananaAlertVIEw {        public static func show(        withTitle Title: String,dismissbuttonText: String,// 新的无痛更改        tintcolor: UIcolor = .yellowcolor())    {        // 具体实现    }}

只要我们给方法添加参数,它就能很好的工作。但是如果我们想要将参数添加到别的东西就不行了,比如 BananaAlertVIEw 上一个按钮被点击后的闭包:

public class BananaAlertVIEw {        // 按钮被点击后的动作    public typealias buttonCallback = (buttonIndex: Int) -> VoID        public static func show(        withTitle Title: String,// 回调参数        dismissbuttonCallback: buttonCallback)    {        // 具体实现    }}// 用法BananaAlertVIEw.show(    withTitle: "This is Bananas",message: "Someone has been monkeying around ?",dismissbuttonText: "Banana",dismissbuttonCallback: { buttonIndex in        // 具体实现    })

但是假如我们需要改变闭包的参数呢?假如客户端同样需要按钮的文本呢?

解决方式就是为 buttonCallback 添加一个按钮文本的参数:

public typealias buttonCallback = (buttonIndex: Int,buttonTitle: String) -> VoID

但是这破坏了一切...当调用 show 方法时,buttonCallback 方法此时需要两个参数,而不是原来的一个了。

// 用法BananaAlertVIEw.show(    withTitle: "This is Bananas",// 破坏了原来的调用    // 闭包需要带有两个参数:buttonIndex 和 buttonText    dismissbuttonCallback: { buttonIndex in        // 具体实现    })

于是我们该怎么办?此时参数对象就该上场了!

解决方案

解决方案是为闭包创建一个参数对象:

public class BananaAlertVIEw {        // 参数对象    public struct buttonCallbackParameters {        let buttonIndex: Int        let buttonTitle: String    }        // 现在只需要一个参数    public typealias buttonCallback = (parameters: buttonCallbackParameters) -> VoID        public static func show(        withTitle Title: String,dismissbuttonCallback: buttonCallback)    {        // 具体实现    }}BananaAlertVIEw.show(    withTitle: "This is Bananas",// 参数对象包含所有调用者需要的参数    dismissbuttonCallback: { parameters in        if parameters.buttonTitle == "Banana" {            // 具体处理代码        }    })

现在需要添加额外的参数时,代码依旧能工作得非常好。buttonCallback 完全不需要变动。

public struct buttonCallbackParameters {        let buttonIndex: Int        let buttonTitle: String        // 新参数        let buttonCount: Int}

当然,你也可以轻松删除或移除参数:

public struct buttonCallbackParameters {        let buttonIndex: Int        // 下个版本中移除 buttonTitle        @available(*,deprecated=2.0)        let buttonTitle: String        let buttonCount: Int}
其他用法

当然,可以重构方法时用更通用的方式来获得越来越多的参数:

public class BananaAlertVIEw {        // 显示警告视图时,视图选项不是必须的    // 这里能够提供默认值    public struct AlertVIEwOptions {        public let dismissbuttonText = "Bananana"        public let tintcolor = UIcolor.yellowcolor()        public let animationDuration: NSTimeInterval = 1    }        public static func show(        withTitle Title: String,options: AlertVIEwOptions)    {        // 具体实现    }}
权衡

和其他设计模式一样,学会和用好完全是两件事,知道它们是好事,但是在使用前需要权衡一下。找到最佳的平衡点是我们码农的工作,需要不断努力才能找到最佳实践?。

对于参数对象来说,好处是能够为未来预留 API,但是这样的预留是有负担的。你不能为此给每个方法和闭包都新建一个新结构体。

所以,请明智的使用!

最后,我强烈推荐观看 @modocache 演讲的完整视频。

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

总结

以上是内存溢出为你收集整理的《重构与模式》Swift 版之参数对象全部内容,希望文章能够帮你解决《重构与模式》Swift 版之参数对象所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1090533.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存