SOLID Swift:第二部分
这是SOLID Swift系列的第二部分:在本文中,我们将研究Liskov替换和界面隔离 。 如果您想追随单一责任原则和开放/封闭原则 ,请随时阅读第一部分。
如简介中所述,第一部分是关于SOLID的前两个原则。 单一责任原则和开放/封闭原则已经是改进代码的两种重要方法! 接下来的两个: liskov替换和接口隔离 。
旁注:如第一部分所述,原则不仅是黑白的,还应根据您的情况,需求和要求进行调整。
非常清楚地表明违反了Liskov替代原则的危险信号之一是:
if shape is Rectangle { ... } else if shape is Square { ... }
如果要添加新形状怎么办? 也许是Triangle
? 我们将不得不在列表中添加另一个 if。 另一个流行的例子更加微妙,可能不会马上被注意到。
想象一下具有width
和height
属性的Rectangle
结构。 Square
可以从Rectangle
派生,因为正方形也具有宽度和高度。 但是,区别当然是对于正方形, width == height
和矩形,该规则不适用。
如果我们要更新Rectangle.width
,那就好了,这对于Square.width
因为Square.height
尚未更改,因此违反了平方的规则。 同样,这违反了LSP。
这听起来像开/关原理吗? 没错,开放/封闭原则与LSP息息相关。 LSP走得更远。
LSP的基本规则是:派生类型(例如Square)必须完全可以替代其基本类型(在这种情况下为Rectangle)。 我们必须确保新的派生类型不会改变其行为的基础。
在开发过程中要记住的有关接口隔离的主要规则是:不应强迫客户端依赖于不使用的接口。
想象一下,我们有一个Employee
,它具有两个功能: lunch()
和work()
因为那是每个Employee
所做的,对吧? 我们定义一个协议:可以通过func lunch()
和func work()
,我们定义了class Employee: Employable {}
,我们就完成了! 我们回家,但是第二天……
老板宣布将向公司添加一些新Employees
。 凉! 我们可以创建新实例,使用它们…哦,现在怎么办? 他们是机器人吗? class RobotEmployee: Employable{}
可以工作,因为我们可以override func lunch()
class RobotEmployee: Employable{}
override func lunch()
来实现空的实现。
但是,这明显违反了接口隔离 原则 。 如果机器人仍然无法午餐,则不应强迫Robot
实现func lunch()
。 我们将如何解决呢?
我们可以创建两个协议:
-
protocol Employable { func work() }
-
protocol Feedable { func lunch() }
然后,我们将雇员定义为class Employee: Employable, Lunchable {}
,并将机器人定义为class RobotEmployee: Employable {}
,这将是接口隔离原理的更好实现。
在此原则上有一个明显的权衡:在设计时进行此操作需要花费时间和精力。 最终您将获得比您可能拥有的协议更多的协议,但这将导致非常灵活的设计。 您对原则的坚持程度,这当然要由您决定。
我们看到的是,明显地违反了LSP和ISP原则,但是,也存在一些解决这些问题的明显方法。 视情况而定,由您决定是否坚守原则。
感谢您阅读本文的第二部分! 如果您想提供反馈 ,或者提供建议或添加到文章中, 请在评论中让我知道 。 谢谢!