专栏首页一个番茄说对swift面向协议的一点理解

对swift面向协议的一点理解

我的第一个正式使用swift开发的项目已经开始三周了,从一开始的不习惯到现在渐渐地有点感觉,让我感到它不仅仅是OC的简单代替,而在设计上其实还是有差别的。

想要首先写下的是: protocol + struct > class

什么意思呢,面向对象的概念基本已经深入人心,但是swift倡导了更高程度的抽象机制,让设计与实现完全分隔开。在写代码的时候首先想到的不应该是写一个superClass,而是考虑是不是应该从一个protocol开始。

我们知道的面向对象有很多好处,比如:封装、多态、抽象、访问控制等等,但是在使用过程中我们也常常遇到很多问题,在Apple的session中也提到了一些:

隐式共享:最常见的是同一个对象有多个引用计数,对其进行更改牵一发而动全身,结果可能并不是你希望见到的。因此我们可能会使用copy(),这不是一个好办法。同时我们在多线程中使用同一个对象的时候可能还会面临更加复杂的情况,可能我们会被迫使用锁,这里又会增加复杂度,越复杂==越多bug!

继承带来的问题:每个类可以有一个父类,它会继承父类中的属性和方法。在子类重载某些方法的或者对某些集成来的属性进行操作的时候可能会比较危险,你得确保你的操作不会破坏父类中需要的某些约束条件。

缺失类型信息:比如当使用父类中继承来的方法的时候,父类中是没办法得到子类的类型信息的,这里就由可能会涉及到向下转型的问题,比如下面用了as!。

class Ordered {
    func precedes(other: Ordered) -> Bool { fatalError("implement me!") }
}

class Label: Ordered { var text: String = "" ... }
class Number: Ordered {
  var value: Double = 0
  override func precedes(other: Ordered) -> Bool {
    return value < (other as! Number).value
    }
}

因此在swift的世界中使用子类相比较而言并不是一个更好抽象机制,使用面向协议的方式有以下好处:

  • 除了引用类型,值类型也可以使用,更加灵活
  • 类型信息得以保障
  • 无法为protocol添加stored property,可以保证在使用的时候不必担心动到了不该动的数据。
  • 不需要像继承那样必须先初始化父类
  • 更加清晰的表述出哪些方法需要被实现。

所以上面的例子用协议来改写之后成了下面的样子。

protocol Ordered {
    func precedes(other: Self) -> Bool
}
struct Number: Ordered {
    var value: Double = 0
    func precedes(other: Number) -> Bool {
      return self.value < other.value
    }
}

改写之后的代码里,不再有涉及到向下转型。

同时在swift中不光支持extension一个已有的class,连protocol也支持扩展,简直业界良心

从swift 2开始,也可以对于协议使用where进行类型限定,这一系列的特性也让我们在开发过程中如虎添翼。

当然,我们在开发过程当中也并不意味着所有的都要采用面向协议的方式,有些需要使用class的时候还是应该坚定不移的使用。只是在写代码之前,停顿一下,思考究竟应该是从一个protocol还是一个class开始。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Scrapy爬虫学习记录

    昨天休息的时候偶然发现了一个的球鞋网站,上面有很多关于球鞋的资讯。于是,决定现学现卖,学习scrapy把数据都给爬下来。

    100000798482
  • 函数响应式编程框架RxSwift 学习——Subject

    简单的比喻下,Observable像是一个水管,会源源不断的有水冒出来。Subject就像一个水龙头,它可以套在水管上,接受Observable上面的事件。但是...

    100000798482
  • 让你在WebView中用JS调Native Object

    之所做这个东西,源于之前项目中需要把一些页面用webView来呈现,但是web中需要调用native的方法,比如获取本地存的某些数据、调用摄像头等等,这里也就是...

    100000798482
  • 【STM32H7教程】第27章 STM32H7的TCM,SRAM等五块内存的动态内存分配实现

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980

    armfly
  • 章节 2.1 可靠的软件 – 灵活,可靠的软件 使用设计模式和敏捷开发

    可靠性和测试 学习目标 学习使软件变得可靠,对于想成为具有竞争力和成功的开发人员是非常重要的。本书大部分将致力于使软件不会失败的开发习惯,技能和实践。本章节的目...

    麦克-堂
  • Socket学习总结系列(一) -- IM & Socket

    Socket通讯在iOS中也是很常见,自己最近也一直在学习Telegram这个开源项目,Telegram就是在Socket的基础上做的即时通讯,这个相信了解这...

    Mr.RisingSun
  • 在Java中如何解析JSON格式数据?

    萤火虫叔叔
  • 关于面试,你是如何面对的呢?

    面试,对于职场的人来说每个人都必须经历的。那作为职场人,看到很多案例,总结的不太笼统,那么该如何面对经常问的话呢?该如何回答比较好呢?以下是通过多个事例进行汇总...

    用户6367961
  • 【智能设备】软硬件测试都有什么

    当这样一个问题摆在我们面前时,相信大部分同学还是无从下手的。有经验的同学,也许可以通过过往的经验逐步总结出要测试的内容,但如果我们需要一个结构化且相对全面的答...

    用户5521279
  • 【每周一坑】田忌赛马

    本周的题目取自著名的历史典故:田忌赛马 背景资料如下 田忌经常与齐国众公子赛马,设重金赌注。田忌的上宾孙膑发现他们的马脚力都差不多,马分为上、中、下三等,于是对...

    Crossin先生

扫码关注云+社区

领取腾讯云代金券