协议与面向对象编程的介绍指南

这篇文章的目的是比较面向对象编程和面向协议编程之间的一些区别,同时用这两种方法建模相同的功能。面向对象编程在20世纪70年代就出现了,而面向协议的编程在最近几年才流行起来,尽管协议/接口已经出现一段时间了。这篇文章的目的不是要在两种架构中选出一个最佳的解决方案,而是试图帮助您为您将要从事的项目类型选择最佳的解决方案。

面向对象编程

面向对象的编程范式是基于一个“对象”的概念,这在大多数编程语言定义的数据结构(例如类),其中包含的信息属性的属性,和执行的操作或一个对象的方法。这种模式允许我们将对象的属性和操作封装到单一类型中,即我们试图在代码中表示的实体。

让我们创建一个基本的类图,展示如何为面向对象的设计设计动物类层次结构。

这张图显示了我们有一个名为动物和三个子类命名鸟,,它将继承超类的所有内部和公共属性和方法。

假设是a电子宠物我们可以使用以下要求创造动物的游戏类型:

  • 我们有三种不同的动物(陆地、空气和水)。
  • 一种动物可以属于多个类别。

让我们开始面向对象的设计:

  • 创建一个AnimalEnvironment用于识别动物可以生存的地方的枚举。
  • 创建一个动物超类,它将包含所有动物的属性。前三个属性是数组AnimalEnvironment动物的名字和年龄。其他三个属性将包含动物在每个环境中的速度。
  • 创造方法,前三个方法是用来让我们的动物锻炼和燃烧卡路里,另外三个是让我们知道动物能做什么。

现在,让我们看看如何子类化动物类,通过创建,类,在我们的关系图中定义。

猫、鸟和鱼对象的子类动物类,我们通过为每个类创建初始化器来开始这些类。为子类,例如,我们指定动物环境为.land,空速waterSpeed因为猫无法在这样的环境中生存。我们还覆盖了属于每个动物的功能,并添加了它们的实现。

如您所见,来自超类的所有信息都暴露给子类,即使不是所有子类都需要所有超类信息。很容易想象这样一种场景:越来越多的代码开始添加到超类中,而超类变得更难维护。即使是最有经验的开发人员,也很容易在数组或速度属性中输入错误的值,从而导致意外的行为。

好处

  • 通过继承实现代码的重用性。
  • 多态性的灵活性。
  • 封装。

缺点

  • Swift是一种单一的继承语言,对于动物类,我们只能有一个超类,这个超类需要包含这三个类别中每一个类别所需的代码。
  • 继承类型不需要的功能。它可能会导致超类膨胀,因为我们可能需要包含只有少数子类需要的功能。
  • 我们不能在父类中创建可以由子类设置的常量。
  • 在Swift中,Value类型不能使用继承,只能使用Reference类型。
  • 打破规则的机会太阳能发电(利斯科夫替代原则),如果设计不好。

Protocol-Oriented编程

与面向对象设计一样,让我们创建一个图表,展示如何以面向协议的方式设计动物类型。

正如我们所看到的,面向协议的设计关注于实现一个协议,该协议关注的是需求,而不是面向对象设计中所设计的细节。这是一个很好的例子ISP(接口隔离原则),客户端不需要知道他们不使用的属性和方法(依赖倒置原则)设计依赖于抽象而不是具体。

让我们开始面向协议的设计:

  • 创建一个动物协议将包含其他协议可以利用的共享需求。
  • 创建一个陆地动物,空中动物和水上动物协议,都将继承自动物协议,并为每一个添加一个速度属性。

该图表向我们展示了协议使用的两种技术:

协议继承:当一个协议可以从一个或多个协议继承需求时。这类似于面向对象编程中的类继承,但不是继承功能,而是继承需求。

协议构成:它允许类型符合多个协议,我们可以看到发生在结构。这在面向对象编程中也是可以实现的,在面向对象编程中,一个类可以有单个或无继承,但符合多个协议。

重要的是要注意,任何符合动物对象的协议,或者符合该协议的任何类型动物协议,将自动访问属性和方法。

现在,让我们看看如何实现,图中定义的结构。正如我们所看到的,面向协议的设计只暴露了每种动物的必要需求,这是分离关注点的好例子。此外,不需要创建自定义初始化器,因为这里我们使用的是结构体而不是

让我们也实现缺失的方法canRuncanFly,canSwim正如我们在面向对象设计中所做的,但这次我们扩展动物协议提供了一些方法,这些方法使我们能够为所有符合规范的类型提供公共实现。

注意,在Swift中,我们使用关键字检查实例是否为特定类型,并且作为关键字将实例视为特定类型。如你所见,我们的结构可以访问所有的方法。

面向对象和面向协议的设计都为我们提供了使用多态性的能力,多态性是针对多种类型的单一接口。让我们看看这两种设计的效果。

正如您所看到的,在面向对象的设计中,对两种方法使用多态性看起来完全相同动物超类是面向协议的设计吗动物是一个协议。

好处

  • 面向协议的设计允许我们使用类、结构和枚举。
  • 我们可以使用协议扩展向符合协议的类型添加功能。
  • 能够将任何属性定义为常量。
  • 协议组合允许一个数据结构实现多种需求。
  • 协议与泛型结合使用时变得非常强大。
  • 更干净的代码。
  • 更容易发现错误。

缺点

  • 滥用协议继承和协议扩展可能导致复杂的系统。

结论

如您所见,我们可以使用这两种范例(面向对象编程和面向协议编程)实现相同的目标。最终,无论您选择使用什么方法,正确设计您的体系结构将为您提供一个坚实而稳定的系统。试着收集你将要从事的项目的所有需求,在纸上进行设计,然后考虑哪种模式更适合你。

最初发表在https://tech.188bet金宝搏官网okcupid.com2020年10月30日

188bet金宝搏官网OkCupid科技博客

阅读OkCupid工程团队每天连接数百万人的188bet金宝搏官网故事

188bet金宝搏官网OkCupid科技博客

188bet金宝搏官网OkCupid的工程团队负责每天为数百万人配对。在OkCupid科技博客上阅读他们的故事188bet金宝搏官网

188bet金宝搏官网OkCupid科技博客

188bet金宝搏官网OkCupid的工程团队负责每天为数百万人配对。在OkCupid科技博客上阅读他们的故事188bet金宝搏官网