S.O.L.I.D是几个重要编码原则(Programming Priciple)的首字母缩写。通常来说,要想构建一个好的软件系统,应该从写整洁的代码开始做起。
SOLID原则的主要作用就是告诉我们如何将数据和函数组织成为类,以及如何将这些类链接起来成为程序。
SOLID原则应该直接紧贴于具体的代码逻辑之上,这些原则是用来帮助我们定义软件架构中的组件和模块的。主要作用是使软件可容忍被改动、更容易被理解且构建可在多个软件系统中复用的组件。
一、SRP:单一职责原则
大部分人对该原则的理解应该都是:某个代码的功能,应保证只有单一明确的执行任务。但这只是其其中的一个维度,正确的理解应该为:每个软件模块都有且只有一个需要被改变的理由或者任何一个软件模块都应该只对某一类行为者负责。
下面用一个反面例子进行讲解:
某个工资管理程序中的Employee类有三个函数calculatePay()、reportHours()和save()。calculatePay()函数由财务部门员工调到。reportHours()函数是由人力资源部门员工使用的。save()函数是由策略团队调用。
这三个函数被放在同一个Employee类中,这样做实际上就等于使三类行为者的行为耦合在了一起,这有可能会导致混乱,例如如果我们只对财务部门的工作时间调整为4小时,但实际结果却是,所有员工调工作时间都被错误调整。
解决方法也有很多:
1、最简单直接的办法是将数据与函数分离,设计三个类共同使用一个不包括函数的、十分简单的EmployeeData类(见图7.3),每个类只包含与之相关的函数代码,互相不可见,这样就不存在互相依赖的情况了。 这种解决方案的坏处在于:程序员现在需要在程序里处理三个类
2、使用Facade设计模式,这样一来,EmployeeFacade类所需要的代码量就很少了,它仅仅包含了初始化和调用三个具体实现类的函数。
3、当然,如果我们想把把最重要的业务逻辑与数据放在一起,那么我们也可以选择将最重要的函数保留在Employee类中,同时用这个类来调用其他没那么重要的函数。
总而言之,以上方法都符合单一职责原则,上面的每一个类都分别容纳了一组作用于相同作用域的函数,而在该作用域之外,它们各自的私有函数是互相不可见的。
二、OCP:开闭原则
该设计原则是由Bertrand Meyer在20世纪80年代大力推广的,其核心要素是:如果软件系统想要更容易被改变,那么其设计就必须允许新增代码来修改系统行为,而非只能靠修改原来的代码。
一句话来理解就是:对扩展开放,对修改关闭。换句话说,一个设计良好的计算机系统应该在不需要修改的前提下就可以轻易被扩展。
OCP是我们进行系统架构设计的主导原则,其主要目标是让系统易于扩展,同时限制其每次被修改所影响的范围。实现方式是通过将系统划分为一系列组件,并且将这些组件间的依赖关系按层次结构进行组织,使得高阶组件不会因低阶组件被修改而受到影响。
三、LSP:里氏替换原则
该设计原则是Barbara Liskov在1988年提出的一个著名的子类型定义。简单来说,这项原则的意思是如果想用可替换的组件来构建软件系统,那么这些组件就必须遵守同一个约定,以便让这些组件可以相互替换。
四、ISP:接口隔离原则
这项设计原则主要告诫软件设计师应该在设计中避免不必要的依赖。
五、DIP:依赖反转原则
该设计原则指出高层策略性的代码不应该依赖实现底层细节的代码,恰恰相反,那些实现底层细节的代码应该依赖高层策略性的代码