Swift 中的面向协议编程是如何点亮我的人生的

本文讲的是Swift 中的面向协议编程是如何点亮我的人生的,


面向对象编程至今已经使用了数十年了,并且成为了构建大型软件约定俗成的标准。作为iOS编程的中心思想,遵循面向对象规范来编写一个 iOS 的应用几乎不可能实现。虽然面向对象有很多优点比如封装性,访问控制和抽象性,但是它也自带有固有的缺点。

  1. 大多数类的情况下,当一个单继承的类需要更多不同类中的函数功能时,你会倾向于使用多继承来实现。 但是大部分的编程语言不支持这一特性,而且会导致类的继承关系变得复杂。
  2. 在多线程环境下,如果所有对象在函数中都是通过引用来传递会导致意想不到的问题。
  3. 因为类与类之间的高耦合性,为一个单独的类写测试单元会很困难。

下面是网上大量的对面向对象的抱怨

All evidence points to OOP being bullshit | Pivotal

Object Oriented Programming is an expensive disaster which must end | Smash Company

Swift 尝试引入一种叫做面向协议的编程新规范来解决传统的面向对象编程中固有的问题。WWDC2015 演讲做了一个令人惊叹的关于面向协议编程的介绍。我迫不及待的想推荐它了。

Swift 在最初的时候是包含值类型的概念。结构体和枚举都是 Swift 中的一等公民,还拥有很多像 propertites, methods 和 extensions 等在大多数语言只有类才有的特点。虽然在Swift中值类型不支持继承,但是通过遵循协议的方式一样能够享受到面向协议的好处。

Ray Wunderlich 的面向协议编程的教程展示了它的能力。

Introducing Protocol-Oriented Programming in Swift 2

现在我将向你展示面向协议编程是如何点亮我的人生的。我的应用程序遵循经典的左侧菜单导航模式(附带一些选项)。这个应用大概有十个不同的 view controller,它们都是继承自一个拥有基础函数和各个界面所需样式的基类 view controller。

和我的应用相似的左侧菜单的应用例子

这个应用依赖于 Webscokets 来与服务器交互。服务器可以随时发送事件,而应用根据用户所在的界面来进行相应的事件响应。举个事件例子的话,比如登出事件,当用户收到了服务器关于这个状态的事件时,应用需要登出并显示登录界面。 在我脑中的第一想法是把登出事件写在基础的 view controller 里面,当事件发生的时候,在需要的 view controller 进行调用。

// BaseViewController.swift
class BaseViewController {
  func logout() {
    //Perform Logout
    print("Logout User")
  }
}

这一步的问题就是并不是每个 view controller 都必须实现这个登出的功能,但是它还是都会继承这个登出的函数。此外不同的 view controller 需要响应不同的事件,所以在基础 view controller 中包含所有的函数并没有什么意义。

幸运地是面向协议编程拯救了我,我声明一个 Logoutable 的协议,那些需要登出功能的 view controller 遵循这个 Logoutable 的协议就可以了。

// Logoutable.swift
protocol Logoutable {
  func logout()
}

// ViewController.swift
class ViewController : Logoutable {
  func logout() {
    //Perform Logout
    print("Logout User")
  }
}

这一个进步带来的问题是我必须在每个需要遵循这个协议的 view controller 中重复这个登出函数的实现。

这正是面向协议编程在 Swift 中的闪光点,因为它给我们提供了协议拓展功能,可以在一个协议中定义一个默认的函数的行为。所以我所需要做的仅仅是在 Logoutable 的协议中写一个带有默认登出行为的实现的拓展,这样这个函数对那些遵循这个协议的 view controller 的来说就是可选的。

//LogoutableExtension.swift
extension Logoutable where Self : BaseViewController {
  func logout() {
    //Perform Logout
    print("Logout User")
  }
}

面向协议编程完全就像魔法一样,不定义任何复杂的继承就够就实现这些功能。现在我就能为不同的事件定义不同的协议并且各自 view controller 就能够遵循它所需要的协议。

面向协议编程是真正地点亮了我的人生,现在每当我需要使用继承或者其他面向对象的原理来构建我的代码时,我会想这能否通过使用面向协议编程的方法来更好的完成这项工作。我不是说它是完美的解决方案但是它仍然值得一试。

如果你喜欢这篇文章的话,请推荐它,这样其他人也可以欣赏它。





原文发布时间为:2016年10月30日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2017-10-18

Swift 中的面向协议编程是如何点亮我的人生的的相关文章

面向协议编程,灵丹妙药或是饮鸩止渴?

本文讲的是面向协议编程,灵丹妙药或是饮鸩止渴?, 在 Swift 中,面向协议编程正值流行.许多 Swift 框架都自称是面向协议编程的,一些开源库甚至将其标榜为特点.而我认为,很多时候眼下的问题本可以用一种更简单的方法解决,但是在 Swift 中我们过度使用各种协议了.简言之:不要教条地使用(或避免)协议. WWDC 2015(苹果电脑全球研发者大会,译者注)中最有影响力的一个分会场就是 Swift 中的面向协议编程.会议表明(当然还有其他内容)你能够用一个面向协议的解决方案替换掉类的层次结构

面向协议编程并非银弹

银弹(Silver Bullet)一词出自IBM大型机之父Frederick P. Brooks Jr.在1986年发表的一篇关于软件工程的经典论文<没有银弹:软件工程的本质性与附属性工作>(No Silver Bullet - Essence and Accidents of Software Engineering).其中的"银弹"是指一项可使软件工程的生产力在十年内提高十倍的技术或方法.该论文强调由于软件的复杂性本质,而使这样"真正的银弹"并不存在

在 Swift 3 上对视图控件实践面向协议编程

本文讲的是在 Swift 3 上对视图控件实践面向协议编程, 学习如何对 button, label, imageView 创建动画而不制造一串乱七八糟的类 你可能听人说过,学到了知识却缺失了行动就好比人长了牙却还老盯着奶喝一样.那好,我们要怎样开始在我的应用中实践面向协议编程? 为了能更加高效的理解下面的内容,我希望读者能够明白 Complection Handlers,并且能创建协议的基本实现.如果你还不熟悉他们,可以先查看下面的文章和视频再回来接着看: 前景提要: Intro to Pro

Swift 面向协议编程入门

本文讲的是Swift 面向协议编程入门, 面向对象编程的思想没毛病,但老铁你可以更 666 的 上图这个人不是我,但这就是使用面向协议编程替换掉面向对象编程之后的感觉. 介绍 这个教程也是为了那些不知道类和结构体根本区别的人写的.我们都知道在结构体里是没有继承的,但是为什么没有呢? 如果你不知道上面问题的答案,那么花几秒钟看下下面的代码.请再次原谅我的排版,我已经让它尽可能的简单明了了. 注:译者已经改过排版了 class HumanClass { var name: String init(n

Spring Framework中的面向方面编程

编程 作为这个介绍Spring框架中的面向方面编程(Aspect-Oriented Programming,AOP)的系列的第一部分,本文介绍了使您可以使用Spring中的面向方面特性进行快速开发的基础知识.使用跟踪和记录方面(面向方面领域的HelloWorld)作为例子,本文展示了如何使用Spring框架所独有的特性来声明切入点和通知以便应用方面.本系列的第二部分将更深入地介绍如何运用Spring中的所有通知类型和切入点来实现更实用的方面和面向方面设计模式.对于AOP的更一般性的介绍,请查看O

面向服务编程

    从最初的面向过程编程,到后来觉得难以理解的面向对象编程,从软件工程的发展历程中来看,这已经成为我们编程路上熟知的两种编程方式.     接触了ITOO项目这么长时间,才发现,不知不觉,我们已经进入了软件工程发展历程之面向服务编程的开发.本篇博客的主题便是面向服务编程.     [一.面向服务编程从何而来?]     想要了解面向服务编程的发展方向以及它在软件行业中所占的地位,我们首先要了解的便是它的起源和发展.没有任何一种方法是一蹴而就的,应该是经历了数十年渐进的演化历程.下面,我们就来

介绍Python中的一些高级编程技巧_python

 正文: 本文展示一些高级的Python设计结构和它们的使用方法.在日常工作中,你可以根据需要选择合适的数据结构,例如对快速查找性的要求.对数据一致性的要求或是对索引的要求等,同时也可以将各种数据结构合适地结合在一起,从而生成具有逻辑性并易于理解的数据模型.Python的数据结构从句法上来看非常直观,并且提供了大量的可选操作.这篇指南尝试将大部分常用的数据结构知识放到一起,并且提供对其最佳用法的探讨.推导式(Comprehensions) 如果你已经使用了很长时间的Python,那么你至少应该听

[译] iOS 响应式编程:Swift 中的轻量级状态容器

本文讲的是[译] iOS 响应式编程:Swift 中的轻量级状态容器, 原文地址:Reactive iOS Programming: Lightweight State Containers in Swift 原文作者:Tyler Tillage 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者:deepmissea 校对者:FlyOceanFish iOS 响应式编程:Swift 中的轻量级状态容器 事物的状态 在客户端架构如何工作上,每一个 iOS

swift 中怎么调用其他类的协议

问题描述 swift 中怎么调用其他类的协议 比如我创建了一个协议protocol 一个类 我想在这个类引用这个协议请问怎么实现? 感激不尽! 解决方案 朋友的需求有点模糊,举个protpcol的例子给朋友吧 创建协议: 遵循协议: 在实现协议的类中实现协议方法