Tag: 面向对象设计

面向协议的编程

面向对象编程自80年代中期开始出现,我们大多数人每天都在使用它。 它使我们能够在程序中模拟现实世界的情况。 就像您有一家大公司的汽车管理应用程序一样。 一辆汽车将以“ 汽车”类别表示,您将为池中的每辆汽车创建对象。 通过抽象,您可以轻松地对更复杂的事物建模。 也许在典型的汽车旁边,您还有卡车或摩托车。 它们都具有马达,但并非都具有门或其他特征。 如您所见,这个概念使编程变得容易得多,这就是我们大多数人使用面向对象的编程语言的原因。 Swift也是面向对象的,但也有一些缺点。 面向对象设计的阴暗面 复杂 摩托车是双向的 , 双向的是机动车 , 机动车是可运输的 。 在大型应用程序中,继承树可以快速增长并变得非常复杂。 项目中的新程序员可能需要一些时间才能解决。 这是个大问题。 我们应该始终尝试降低复杂性并使其易于实现新功能。 并发 您可能希望使用线程来提高软件性能。 但是,处理数据时会遇到困难。 类在所有线程之间具有“共享状态”:类的数据位于堆内存中。 虽然每个线程都有自己的堆栈,但堆是共享的。 当多个线程尝试操纵对象的数据时,事情变得非常困难。 最后,您将创建一个互斥锁,这会导致性能高昂且容易出错(死锁)。 超类的实现 想象一下,您想实现一辆电动踏板车。 电动踏板车是MotorVehicle。 现在,MotorVehicle迫使您实现方法“ openDoors()”和“ closeAllDoors()” 。 实施MotorVehicle类的人没有想到某天某人想要实施电动踏板车的情况。 我已经看过很多次了,尤其是在大型复杂项目中。 您可能最终以空的正文和愚蠢的注释来实现这些方法。 这是不好的 Swift中没有抽象方法 在Java中,我可以使用抽象函数声明抽象类。 您不能创建抽象类的对象,但是每个实现都会继承该类中定义的非抽象方法。 Swift不支持此功能。 这就是为什么我最近在生产代码中遇到以下问题: 使用协议和值类型! 了解发生了什么:值类型与引用类型 创建类的对象时,程序将分配内存。 这项工作将由操作系统完成。 并且由于您以后可能想读取或修改数据,因此操作系统会告诉您内存中数据的存储位置。 这是您的数据位于内存中的“地址”。 该地址是一个十六进制数,例如“ 0xCAFEBABE” 。 以后,当您访问数据时,可以通过引用内存中的地址来访问数据。 […]

Swift的SOLID面向对象设计原则

iOS首席工程师Buymie的Mnats Karakhanyan 好的软件系统应该具有好的架构和构建块。 如果没有很好地构建模块,那么体系结构就没什么大不了的,那么您最终可能会使用构建良好的模块构建一个糟糕的系统。 这就是SOLID原则的用武之地。 SOLID原理告诉我们如何将我们的功能和数据结构安排到类中,以及如何将这些类互连。 注意: “类”一词并不意味着这些原则仅适用于面向对象的软件。 类只是功能和数据的耦合分组。 每个软件系统都有这样的分组。 SOLID是5条原则的首字母缩写,代表: S:单一责任原则(SRP) O:开闭原理(OCP) L:李斯科夫替代原理(LSP) 一:接口隔离原理(ISP) D:依赖反转原理(DIP) 这些原则的目标是创建以下软件结构: 容忍变化 容易理解,并且 是可在许多软件系统中使用的组件的基础。 SRP:单一责任原则 类或模块应该有一个更改理由,并且只有一个更改理由 该原则为我们提供了责任的定义和班级规模的准则。 班级应该承担一项责任-改变的原因之一。 违反SRP的示例。 让我们看看这堂课有什么样的责任? 从API检索数据 解析API响应 将数据保存在数据库中 我们可以解决此问题,将职责移至类: 注意:听到这个名称太容易了,然后假设它意味着每个模块都只能做一件事 。 有这样的原则。 一个函数应该做一件事情,并且只能做一件事情。 违反原则的症状是意外复制和合并。 OCP:开放封闭原则 软件实体(类,模块,功能等)应打开以进行扩展,但应关闭以进行修改 让我们看一个违反OCP的例子。 考虑类AnaliticServise,该类正在跟踪Facebook中的事件。 现在,我们还想增加在Google Analytics(分析)中跟踪相同事件的可能性。 不违反OCP的解决方案可能如下所示: 注意:遵循OCP通常会引入新的抽象级别,这会增加我们代码的复杂性。 您想专注于最有可能在您的设计中发生变化的领域,并在其中应用原理。 LSP:李斯科夫替代原则 令Φ(x)是关于类型T的对象x的可证明性质。那么对于类型S的对象y,其中S是T的子类型,则Φ(y)应该成立。