SOLID原理及iOS和Swift中的示例(第2部分)

在第1部分中,我解释了最重要的两个原则(单一职责和开放/封闭)。 如果您想学习,请点击以下链接:

iOS / Swift中的SOLID原理与示例(第1部分)
SOLID原则相对较旧,但适用于任何语言的任何OOP代码库的概念都非常有用。 medium.com

在这一部分中,我将尝试解释Liskov替代和界面分离原理。

里斯科夫换人原则:

Liskov替换原理(LSP)指出,程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。 这意味着当您从类或抽象类继承或实现接口(协议)时,无论使用了您的子类接口或类,您的对象都应该是可替换和可注入的。 该原则通常被称为按合同设计,或者在Swift社区中最近被称为面向协议的编程 。 此原则的主要信息是,您不应违反从您的子类继承来的接口要履行的约定,并且通过子类化,这些子类可以在以前使用超类的任何位置使用。 例如,如果我们有PostsStorage类 ,那么根据Liskov的“替换原理”,我们可以说,如果我们从它继承子类 ,我们将其称为BetterPostsStorage ,那么在所有使用原始PostsStorage的地方 ,我们都可以使用BetterPostsStorage ,而我们的应用程序将请勿以任何方式破坏或行为不检。

接口隔离原理:

接口隔离原理(ISP)表示,许多特定于客户端的接口比一种通用接口要好。 它还指出,不应强迫任何客户端依赖和实现不使用的方法。 这就是说,当您创建类要实现的接口(协议)时,您应该努力并依赖于抽象性而不是特异性,但是直到浪费成为浪费,在这种情况下您必须实现一堆新类甚至不需要的方法采用。

如果您想了解接口和继承之间的区别,请先阅读以下文章:https://medium.com/@ansujain/interfaces-vs-inheritance-in-swift-1f48c85948b8

缺少一个更好的(简短的)示例,让我们假设我们具有以下类和接口:

  协议WorkerInterface { 
func eat()
func work()
}
  类Worker:WorkerInterface { 
  func eat(){ 
打印(“工人在吃午餐”)
}
  func work(){ 
打印(“工人的工作”)
}
}
  类承包商:WorkerInterface { 
func eat(){
打印(“承包商吃午餐”)
}
func work(){
打印(“承包商的工作”)
}
}
  班主任{ 
私人让工人:[WorkerInterface]
初始化(工人:[WorkerInterface]){
自我工作者=工人
}

func manage(){
worker.forEach {(worker:WorkerInterface)在
worker.work()
}
}
}
  让worker1 = Worker() 
让worker2 = Worker()
让承包商= Contractor()
  让经理=经理(工人:[工人1,工人2,承包商]) 
manager.manage()

在这里,我们有一个WorkerInterface ,它有两个方法eat()work() 。 我们有两个实现它的类: WorkerContractor 。 我们有一个Manager ,它依赖于WorkerInterface在每个传递的worker和Contractor对象上调用work()来启动工作。 一切都很好,我们在这里假设所有的工人和承包商都是可以工作但又需要吃饭的人,因此在他们俩中实施eat()方法是完全合理的(我们假设eat()方法是在应用程序中其他位置调用了这些对象)。

但是,当我们引入一个符合同一WorkerInterfaceRobot类时,这很快就变得不合理了:

  机器人类别:WorkerInterface { 
//在这里什么也不做。 因为机器人不吃东西。
func eat(){}

func work(){
打印(“机器人正在工作”)
}
}

这违反了ISP,因为我们的机器人不需要吃东西,并且机器人被迫实现它不完全需要的接口,因此是一个空eat()方法。

相反,我们需要提取更好,更具体的接口并改为使用它们:

  协议WorkableInterface { 
func work()
}
  协议FeedableInterface { 
func eat()
}
  类Worker:WorkableInterface,FeedableInterface { 
func eat(){
打印(“工人在吃午餐”)
}
  func work(){ 
打印(“工人的工作”)
}
}
  机器人类别:WorkableInterface { 
func work(){
打印(“机器人正在工作”)
}
}

现在,我们依赖于Manager使用的更特定的WorkableInterface ,而Robot不必实现不需要的东西。 简而言之,这就是接口隔离原理的全部含义。 您必须先做一些更多的设计才能正确使用接口/协议,或者在现有系统中使用适配器来解决它。 但是ISP也可以帮助您在代码中维护Liskov的替换原则。

今天就这样,希望对您有用。 请让我知道您的想法和意见:)。 如果您喜欢它,请随时按below下面的鼓掌按钮帮助他人找到它! 在下一部分中,我将编写依赖关系反转原理。