面向协议的编程

面向对象编程自80年代中期开始出现,我们大多数人每天都在使用它。 它使我们能够在程序中模拟现实世界的情况。 就像您有一家大公司的汽车管理应用程序一样。 一辆汽车将以“ 汽车”类别表示,您将为池中的每辆汽车创建对象。 通过抽象,您可以轻松地对更复杂的事物建模。 也许在典型的汽车旁边,您还有卡车或摩托车。 它们都具有马达,但并非都具有门或其他特征。
如您所见,这个概念使编程变得容易得多,这就是我们大多数人使用面向对象的编程语言的原因。 Swift也是面向对象的,但也有一些缺点。

面向对象设计的阴暗面

复杂

摩托车是双向的双向的机动车机动车是可运输的 。 在大型应用程序中,继承树可以快速增长并变得非常复杂。 项目中的新程序员可能需要一些时间才能解决。 这是个大问题。 我们应该始终尝试降低复杂性并使其易于实现新功能。

并发

您可能希望使用线程来提高软件性能。 但是,处理数据时会遇到困难。 类在所有线程之间具有“共享状态”:类的数据位于堆内存中。 虽然每个线程都有自己的堆栈,但堆是共享的。 当多个线程尝试操纵对象的数据时,事情变得非常困难。 最后,您将创建一个互斥锁,这会导致性能高昂且容易出错(死锁)。

超类的实现

想象一下,您想实现一辆电动踏板车。 电动踏板车是MotorVehicle。 现在,MotorVehicle迫使您实现方法“ openDoors()”“ closeAllDoors()” 。 实施MotorVehicle类的人没有想到某天某人想要实施电动踏板车的情况。 我已经看过很多次了,尤其是在大型复杂项目中。 您可能最终以空的正文和愚蠢的注释来实现这些方法。

这是不好的

Swift中没有抽象方法

在Java中,我可以使用抽象函数声明抽象类。 您不能创建抽象类的对象,但是每个实现都会继承该类中定义的非抽象方法。 Swift不支持此功能。 这就是为什么我最近在生产代码中遇到以下问题:

使用协议和值类型!

了解发生了什么:值类型与引用类型
创建类的对象时,程序将分配内存。 这项工作将由操作系统完成。 并且由于您以后可能想读取或修改数据,因此操作系统会告诉您内存中数据的存储位置。 这是您的数据位于内存中的“地址”。 该地址是一个十六进制数,例如“ 0xCAFEBABE” 。 以后,当您访问数据时,可以通过引用内存中的地址来访问数据。 当您将对象的变量传递给另一个方法时,将仅传递数据的引用,而不传递数据本身。 这意味着当您在方法中修改数据时,数据将在其他地方被修改。
值类型将在堆栈而不是堆上分配。 当您使用值类型调用方法时,将为该方法调用创建一个新的跟踪框架,并复制您的值类型。 当您操作值类型的数据时,由于已复制数据,因此仅在当前堆栈框架上对数据进行操作。 这意味着它只是在调用的方法中操作,而不是在您来自的方法中操作。

从协议开始
首先考虑需求。 然后编码。 这样可以为您节省大量的重构时间。 协议迫使您考虑要提供的功能以及执行此操作所需的数据。 每个人都是API设计人员。

另一点是,对于其他程序员而言,根据您定义良好的协议进行开发要容易得多。 我经历了很多辅助功能的大型课程,因此我必须首先弄清楚该调用什么。 协议隐藏了复杂性。 特别是在有团队的大型项目中。 可以将其视为一种“自我记录代码”

使用“特质”而不是大量的超类

特性是适用于所有实现的功能。 考虑一个“可航行的” :所有帆船⛵️都是可航行的。 为了骑行,您必须“起航”。 假设所有“ Sailable”的进度都相同。 您可以提供适用于所有帆船的“起航”特征。

当您创建一种新型的帆船时,您只需使其成为“ Sailable”并调用“ setSail”方法即可。

类与结构

与类相比,结构具有一些优势,因此出于以下原因,我建议将其比类更好:

异步环境中的问题

我已经告诉过您有关在线程中使用类的问题。 多个线程可能会同时修改您的数据。 您可以通过创建互斥锁来防止此情况,但是此线程锁的性能不是很高,并且确实容易出错(死锁)。

参考计数

如果您在我推荐雷·温德利希(Ray Wenderlich)的这篇文章之前没有听说过引用计数,请访问: https ://www.raywenderlich.com/134411/arc-memory-management-swift

Swift使用引用计数自动处理内存管理。 当您从类创建对象时,计数将增加为1。有时,当不再有引用时(当您完成工作时),计数将减少为0。如果计数为0,则该对象将被删除。
正如我在上面告诉您的那样,值类型将在堆栈上分配。 值类型没有引用,因此您不能计算任何引用。 例如,结构的实例将保留在堆栈上,直到该方法结束并且弹出堆栈框架为止。
对于编译器来说,这种情况要简单得多。 通过引用计数,有时可能会导致内存泄漏。 而且您不必担心牢固或脆弱的关系。

性能

结构对于表演者而言远胜于课堂。 在此示例中,结构的速度提高了50.000倍https://stackoverflow.com/a/24243626
值类型的堆栈访问更快,并且您没有引用计数开销。

结构是如此惊人! 我不再使用类

即使是出色的性能结构也有局限性。 考虑一下数据结构。 例如,二叉树。 您不能在结构中再次使用结构。 在这种情况下,您必须使用类。