POP(面向协议的编程)-简介

在此处找到原始帖子。

前言

计算机是由多个硬件组件组成的复杂机器。 然后是一个软件层,可以有效地利用这些组件来执行所需的任务。 这些复杂的机器很多时候互相交谈以共享信息或委派一些任务。 所有这些任务在某个时间点都会处理数据。 对整个生态系统的研究被广泛称为计算机科学。 科学领域,其整个重点是使一组任务自动化。 我们将不断发展和改善现有的生态系统,并期望它能为我们做更多的事情。 在硬件组件上不时有值得称赞的改进。 随后,我们改进了软件方法,以充分利用这些笨拙的组件。 我们发明了操作系统,内核,编译器,并逐步对其进行改进以与硬件相匹配。 为了构建这些功能强大的软件,需要开发出具有更多功能和更多功能的新编程语言。 每种编程语言均出于一组目的而存在,并且支持一个或多个编程范例。

这样的范例之一就是面向对象的编程(OOP),它于1960年代初期引入,并从那时起被广泛使用。 这种范式要求我们根据对象来思考一切。 OOP通过其核心原理(抽象,封装,继承和多态性)具有解决现实问题的强大能力。 因此,许多编程语言已成为OOP的主要范例。 诸如C ++,JAVA,Objective-C等OOP语言通过分类,子分类,方法重载,抽象(协议)等支持了核心原理。

不过有一些注意事项–

  1. 所有这些功能仅可用于对象(引用类型)。 诸如结构和枚举之类的值类型无法利用这些功能,因此它们仅保留了数据存储空间而已。
  2. 我们失去了值类型是线程安全的巨大优势。 结果,我们不懈地致力于解决对象(引用)的线程安全问题。
  3. 同样,大多数OOP语言由于其性质的复杂性而不支持多重继承,因此不支持多重继承。 例如:假设歌手演员都从其父艺术家Artist继承,他们都免费获得了Artist实现的通用功能

但是,如果要求说某些歌手也可能是演员,那么继承树将看起来像–

在这里,我们也将每个歌手都设置演员 ,当歌手不是演员时,这会强制不相关的功能。

期望

这些惊人的OOP功能也应该有一种可用于值类型的方法,这样我们就不必担心解决线程安全的成本。 而且,如果我们可以在不给我们的类型带来太多复杂性的情况下带来多重继承,那么我们就可以完全避免上述问题。

解决方案—面向协议的方法

时间需要不同的思维方式。 超越OO方式的思考。 面向协议的方法。 但是首先,什么是协议? 协议是一组规则和要求(方法和属性),类型(值或引用)需要满足。 将协议视为其要求的抽象蓝图。 一个类型可以相应地实现这些要求,并称其符合协议。 此外,一种类型可以符合多种协议。

让我们尝试通过面向协议的方法来解决上述问题–

我们声明了三个协议, 艺术家演员歌手演员歌手都继承自Artist协议。 每个协议都已声明其要求。 例如,符合Artist协议的类型需要在其实现中定义名称和年龄。 同样,符合Singer协议的类型需要提供nameagesongsaddSong()的实现

接下来,我们定义了一个名为OnlySinger的类,该类符合Singer协议。 我们定义了另一个类SingerActor,它继承自OnlySinger,以便它获取Singer协议的所有已实现功能,并使其与Actor协议兼容,从而可以实现其必需的功能。

这就是Swift中的样子–

protocol Artist { 
var name: String {get set}
var age: Int {get set}
}
 protocol Actor: Artist { 
var movies: [String] {get set}

func addMovie(movie: String)
}
 protocol Singer: Artist { 
var songs: [String] {get set}

func addSong(song: String)
}
 class OnlySinger: Singer { 
//OnlySinger conforms to Singer protocol
//Hence it needs to implement its requirements
var songs: [String] = []
var name: String = ""
var age: Int = 0
func addSong(song: String) {
//Add song to singer's song list
}
}
 class SingerActor: OnlySinger, Actor { 
//SingerActor conforms to Singer(through OnlySinger)
//as well as Actor protocol.
//Hence it needs to implement Actor's requirements
var movies: [String] = []

func addMovie(movie: String) {
//Add movie to actor's movie list
}
}

与子分类方法相比,此方法看起来更干净。 我们不会泄漏任何其他功能。 这是一种面向协议的方法,其中主要的事情由协议驱动。 他们设置规则和要求以及根据他们的需要实施它们的类型。

协议的一个优点是可以扩展它们以提供其要求的默认实现。 例如,如果协议的某些要求在其所有符合类型中都具有通用实现,则这些要求可以由协议本身实现。 所有符合条件的类型均免费获得默认实现,而无需再次实现。

协议是Swift和Objective-C编程语言中可用的语言构造。 但是,并非所有功能都可以在Objective-C中使用。 尽管Swift支持OOP和功能编程范例,但它的核心是面向协议的语言。 Swift中的大多数值类型(如数组,字典,字符串等)都基于协议,并基于此新范式构建。

Swift无疑催生了新的编程范例,以克服OOP的警告。 POP可以完全取代OOP吗? 我认为目前很难对此发表评论,但是POP确实是一种干净的方法,并且在许多情况下都具有优势。