设计原则
单一职责原则
单一职责原则(SRP)的职责被定义为 “引起变化的原因”。如果一个方法承担过多的职责,那么在需求的变迁中,需求改写这个方法的可能性就越大(修改代码是一件危险的事情)。
SRP原则体现为:一个对象(方法)只做一件事情。
SRP原则的应用难点在于如何去分离原则?
并不是所有职责都应该一一分离。
- 如果两个职责总是同时变化,没必要分离他们。比如:fetch的封装和发送请求
- 职责的变化轴线仅当它们确定会发生变化时才具有意义,也没有必要主动分离他们。
优点:
- 降低了单个类或者对象的复杂度,按照职责把对象分解成更小的粒度,这有助于代码的复用,也有利于进行单元测试。当一个职责需要变更的时候,不会影响到其他的职责。
缺点:
- 会增加编写代码的复杂度。当我们按照职责把对象分解成更小的粒度之后,实际上也增大了这些对象之间相互联系的难度。
最少知识原则
最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。
软件实体包括:对象、类、模块、函数、变量等。
简单来说就是应当尽量减少对象之间的交互,如果两个软件实体之间不必彼此通信就不要发生联系。通过引入第三章对象来承担通信作用。
主要手段是封装的时候只暴露必要的接口,限制变量可见性。
例:
- 中介者模式
开放-封闭原则
开放-封闭原则定义为软件实体(类、模块、函数)等应该是可以扩展的,但是不可修改。
当需要改变一个程序的功能或者给这个程序增加新功能的时候,可以使用增加代码的方式,但是不允许改动程序的源代码。
最常见的是过多的条件分支语句造成程序违法开放-封闭原则。因为每当需要增加一个新的 if
语句时,都要被迫修改源代码,包括使用 switch-case
。
常用解决手段:利用对象的多态性。
- 找出程序中要变化的地方封装起来,把稳定不变的部分和容易变化的部分 分隔开。(如动物都会叫是不变的,但具体怎么叫是可变)。
- 放在构子函数,预判程序下一步操作(模板方法模式)。
- 使用回调函数。
但事实上要让程序保持完全封闭是不容易做到的,只能尽可能避免修改,必要修改时也修改相对容易的地方。比如修改配置文件比修改源码来的简单。
附加:代码重构
- 提炼函数
避免出现超大函数。提炼出的函数有助于代码复用。
- 合并重复的条件片段
javascript
if(currPage <= 0) {
currPage = 0
jump(currPage)
} else if(currPage >= totalPage) {
currPage = totalPage
jump(currPage)
} else {
jump(currPage)
}
// 改为
if(currPage <= 0) {
currPage = 0
} else if(currPage >= totalPage) {
currPage = totalPage
}
jump(currPage)
把条件分支语句提炼成函数
合理使用循环
提前让函数退出代替嵌套条件分支
传递对象参数代替过长的参数列表
尽量减少参数数量
少用三目运算符
合理使用链式调用
分解大型类
用return退出多重循环