模块和变更控制:为什么对Swift中基于协议的编程感到兴奋

你曾经没有冰箱住过吗? 自从我们一个多月前破产以来,这就是我一直在做的事情。 原来,我们的厨房在冰箱周围进行了翻新,所以把破损的冰箱搬出来是一场噩梦。 整个经历使我开始思考我们在多大程度上依靠我们的设备为我们做不同的事情。

当我们第一次买到冰箱时,我真的很兴奋,因为它也有一个饮水机。 因此,现在,我们的冰箱不仅用于储存食物并保持冷藏,还可以用来取水。 我们已经有一个饮水机,我们的厨房水槽。 我们用它来洗碗,但是我们也有一个洗碗机。 我们有许多不同的设备,它们以不同的方式完成相同的任务,以完成各种任务。

作为一个新手程序员,我一直在思考如何在代码中表示事物。 通常,在编写代码时,我的理念是问“完成此任务看起来像什么? 涉及的机制和步骤是什么? 所以预期的条件和结果是什么?”因此,当我了解到所有可以做的事情(例如Swift)时,我会以类比的方式来使用它们来解决生活中的问题。

所以我有一个装满电器的厨房,我想用代码表示它们。 传统上,使用面向对象编程,我将为每种通用设备类型定义一个类,然后具有特定的子类来共享其大多数方法和属性,并添加自己的独特方法和属性。 太好了,但这就是问题所在:就像一个程序一样,我的厨房经历了无数次迭代。 如果我在12月为我的厨房编写代码(我将其称为以前的版本为Kitchen 2.0),因为我的冰箱分配了水并且也是唯一使食物保持低温的东西,也许我会先定义Sink类,然后才有了冰箱包括一个水槽对象以允许其分配水。 我本来让洗碗机继承了洗碗的能力,却没有分配水的能力。

好吧,现在冰箱坏了,我们有一个迷你冰箱。 那根本不分配水。 因此,如果我要更新厨房代码,则必须为不继承水分配功能的迷你冰箱增加一个新类。 好吧,这就是这样的大型项目的本质。

但是,当我们买到新冰箱时会怎样? 技术在10年中取得了长足的进步,现在出现了一种全新的设备,即“智能设备”,可以访问互联网。 在OOP范式中,从经过翻新的Kitchen 2.o到智能电器Kitchen 3.o,将是一项疯狂的工作。 我必须决定是否重新分类几乎所有内容,使冰箱成为智能设备和冷却设备的父类,是否要从小型冰箱继承还是成为其父对象,还是要创建新的智能设备?反对并将其纳入我的课程。

更改父类时,我必须返回并确保所做的更改没有破坏任何子类。 我必须进入每个子类,并确保我要考虑其内部方法中对父类代码的任何更改,并确保我覆盖了我不想继承或不想继承的任何方法。功能有所不同。 整个过程将花费一些时间来实现我真正兴奋的超酷“智能设备”功能。 Kitchen 3.o更新看起来是一场巨大的噩梦。

此外,您可以看到继承如何在其头上代表其自身的概念基础。 通常,您会想象一个简单的对象从更复杂的对象继承其功能。 但是,继承模型具有从简单对象继承的更复杂的对象。 这会导致更改从简单且易于修复的对象向外过滤到复杂且难以修复的对象中。

这就是为什么我对面向协议的编程感到如此兴奋的原因。 协议旨在概述对对象的要求,以便它们可以与其他对象安全地交互。 但是从我目前的厨房状况来看,我可以看到POP的多功能性对于真正实现OOP设定的目标将有真正的帮助。 我可以通过使用Swift的协议从传统的继承模型切换到模块化(面向方面​​)模型来实现。 它将使Kitchen 3.oa变得束手无策!

在以协议为中心的模型中,我可以将可用于多个类的所有常用方法划分为协议。 协议将允许我定义几个类共有的功能,并对操作它们所需的变量实施要求。 在下面,您可以看到如何使用协议在Swift中实现我的Container模块。 我使用“ _m”来区分我的模块和其他类型的协议。 您可以看到我正在设置变量“ storedItems”的要求。 我需要定义此变量是否可以直接访问,并且如果我将Structs与此模块兼容,则需要定义将其修改为Mutating的方法。

为了允许类使用模块,我需要像普通协议一样将其添加到类声明中。 现在,该类的任何实例都可以使用它从模块中获得的方法。 我不必声明这些方法即可编译我的代码,如果需要添加功能或完全替换它们,也可以覆盖它们。 我可以创建另一个具有相同名称的功能,以添加其他功能。 在下面,您可以看到我是如何使用Container和WaterDispenser模块从Kitchen 2.0实现冰箱类的。

通过创建模块的能力,我可以建立以前在“洗碗机”,“炊具”和“冷却器”协议中继承的所有其他方法。 我可以将所有这些组合成不同的排列,并将它们挂接到具有每个设备的独特属性的小类或结构上。 当我要添加新设备时,我只列出了它可以做的所有事情! 现在,当我进行更改时,它们只会在协议中发生。 即使在最复杂的对象中,我也只需寻找对象修改或调用其模块功能之一的错误。 我可以通过拆分模块并在需要的地方添加它们来分离必要和不必要的功能。

所以我买了新冰箱。 我添加了“冷却器”协议,“容器”协议和“饮水机”协议。 在类函数中,我提高了容器和冷却器的属性,因为它们非常大,并且比我们使用的迷你冰箱更好地保持低温。 我降低了饮水机的功能,因为我不会用它来填充意大利面条锅。 我对Kitchen 3.o更新的唯一大工作就是将新的智能设备功能添加到新的“智能设备”协议中。 这样,在Kitchen 3.0中,当我获得Smart Microwave时,可以毫无问题地将其添加!

我不是专业人士,但我也可以在业务方面看到好处。 因为我将时间集中在添加新功能上,所以不必花费大量时间对所有内容进行重新分类。 不必仔细研究整个厨房代码,以确保我对类结构所做的所有更改都没有引入大量新错误,我可以集中精力使新的“智能设备”功能尽可能地发挥最大作用。是!

因此,这就是我认为Swift的协议将使继承变得通用且版本控制变得轻松的原因。 我全心全意地对Swift进行了新的更改,我很高兴能用它来考虑以新的方式解决问题。