美文网首页
协议的实用性

协议的实用性

作者: George2016 | 来源:发表于2017-06-05 12:10 被阅读7次

这是一个能展示(之前的方式)有多残暴的例子:

class PresentErrorViewController: UIViewController {
    var errorViewIsShowing: Bool = false
    func presentError(message: String = “Error!", withArrow shouldShowArrow: Bool = false, backgroundColor: UIColor = ColorSalmon, withSize size: CGSize = CGSizeZero, canDismissByTappingAnywhere canDismiss: Bool = true) {
        //写下了复杂的,脆弱的代码
    }
} 
//说一下,有100个class继承了这个class 
EveryViewControllerInApp: PresentErrorViewController {}

随着项目的进行事情马上变的明了:并不是每一个UIViewController需要这个error逻辑,或是真的需要这个class所提供的每一个功能。我团队里任何一个人都可以轻易的在这个superclass里改点儿什么,从而影响整个app。这就让代码变得脆弱。还使得代码呈现出了多态。当本应该是由子类决定它自己的行为,这里的superclass却给帮着决定了。下面是在swift 2.0中我们如何用POP来更好的构建这段代码:

protocol ErrorPopoverRenderer {
    func presentError(message: String, withArrow shouldShowArrow: Bool, backgroundColor: UIColor, withSize size: CGSize, canDismissByTappingAnywhere canDismiss: Bool)
} 
extension UIViewController: ErrorPopoverRenderer { //使所有遵从于ErrorPopoverRenderer协议的UIViewController具有一个presentError的默认实现
    func presentError(message: String, withArrow shouldShowArrow: Bool, backgroundColor: UIColor, withSize size: CGSize, canDismissByTappingAnywhere canDismiss: Bool) {
        //加上呈现error视图的默认实现
    }
} 
class KrakenViewController: UIViewController, ErrorPopoverRenderer { //Drop the God class and make KrakenViewController conform to the new ErrorPopoverRenderer Protocol.
    func methodThatHasAnError() {
        //…
        //抛出error,原因是Kraken海妖今天吃人会感到不适。
        presentError(/*blah blah blah 好多参数*/)
    }
}

看,这里发生了很炫酷的事情。我们不仅消除了上帝类的存在,还让代码更加的模块化并增强了它的扩展性。通过创建一个 ErrorPopoverRenderer协议,就会让任何遵循了该协议的class具有呈现出一个ErrorView的能力。还不止这些,我们的KrakenViewController class不用必须实现presentError这个函数,因为我们扩展了UIViewController,让它提供了一个默认实现。

唉不过等下!这有个问题!我们每次想要呈现一个ErrorView的时候都必须要去实现每一个参数。这就有点儿让人不爽了,因为我们不能在protocol协议函数声明中为参数提供默认值。

我还挺喜欢这些参数的!更糟的是在让代码更具模块化特征的过程中我们引入了复杂度。还是继续吧,用swift 2.0中新加的一个小妙招来多少的补偿一下:

protocol ErrorPopoverRenderer {
    func presentError()
} 
extension ErrorPopoverRenderer where Self: UIViewController {
    func presentError() {
        //在这里加默认实现,并提供ErrorView的默认参数。
    }
}
class KrakenViewController: UIViewController, ErrorPopoverRenderer {
    func methodThatHasAnError() {
        //…
        //抛出error,原因是Kraken海妖今天吃人会感到不适。
        presentError() //Woohoo! 没有参数了!我们现在有默认实现了!
    }
}

好了,现在看起来已经很不错了。我们不仅消除了这些烦人的参数,还用swift 2.0的新特性在protocol的层级上用Self给了presentError一个默认实现。用Self意味着当且仅当协议的遵循者是继承自UIViewController的情况下,这个扩展才会有效。这就让我们能够把ErrorPopoverRenderer真的当做是一个UIViewController,而甚至不需要对后者做扩展!更棒的是,从现在开始,Swift的运行时是以静态调度而非动态调度去调用presentError()方法。大致的意思就是我们在函数调用点给presentError()方法增强了一点性能。

原文转载

相关文章

  • 协议的实用性

    这是一个能展示(之前的方式)有多残暴的例子: 随着项目的进行事情马上变的明了:并不是每一个UIViewContro...

  • 如何阅读【实用性书籍】

    【what】 什么是实用性书籍? 1.实用性书籍谈的是有关行动的问题。 2.实用性书籍包含了规则--原理、准则或任...

  • 《如何阅读一本书》第十三章思维导图

    如何阅读实用性的书 本章告诉读者,阅读实用性的书,必须从目的和结果出发,只有行动,才能把实用性书真正读懂。 实用书...

  • 1月18日读书笔记

    读《新课标解读》学习任务群7 实用性阅读与交流引导学生学习当代社会生活中的实用性语文,包括实用性文本的独立阅读和理...

  • 如何阅读一本书~7

    第三篇 阅读不同读物的方法 第十三章 如何阅读实用性的书 论说性作品区分实用性与理论性。 实用性:有关行动,作...

  • 2019-02-10

    实用性强的ppt

  • 发展型学习任务群

    发展型学习任务群主要包括实用性阅读与交流、文学阅读与创意表达和思辨性阅读与表达。首先,实用性阅读侧重实用性,阅读叙...

  • 如何阅读实用性书籍和想象文学

    懂得阅读方法的人,文学品味都很高。 一、阅读实用性书籍 1.在阅读实用性书籍时,先要了解一件事:任何实用性的书籍都...

  • 如何阅读一本书(十八)

    阅读不同读物的方法 一、如何阅读实用型的书(一) 两种实用性的书 关于实用性的书 有一件事要牢记在心: 任何实用性...

  • 实用性

    读过很多书面性之类 报刊 简书 即看书的各种app 发现个特点,就是实用性的很少本人认为实用性较小的向大家分享...

网友评论

      本文标题:协议的实用性

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