SOLID 原则
单一职责原则(SRP)
一个类或者模块只负责完成一个职责,不要设计大而全的类, 要设计力度小,功能单一的类,单一职责原则是为了实现代码高内聚,低耦合,提高代码的复用性,可读性, 可维护性.
开闭原则(OCP)
对扩展开放,对修改关闭. 添加一个新的功能应该是在已有的代码基础上扩展代码(新增模块,类,方法等), 而非修改已有代码.
开闭原则不是完全杜绝修改, 而是以最小的修改代码的代价来完成新功能的开发.
里氏替换原则(LSP)
子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏
哪些操作违背了LSP
- 子类违背父类申明要实现的功能
- 子类违背父类对输入输出,异常的约定
- 子类违背父类注释中所罗列的任何特殊说明
接口隔离原则(ISP)
客户端不应该强迫依赖它不需要的接口.
如果把接口理解为一组接口集合, 可以是某个微服务的接口, 也可以是某个类库的接口, 如果部分接口只被部分调用者使用,我们就需要将这部分接口隔离出来,单独给这部分调用者使用,而不强迫其他调用者也依赖这部分不会调用的接口.
如果把接口理解为单个API接口或者函数, 部分调用者只需要函数中的部分功能, 那我们就需要把函数拆分成粒度更细的多个函数, 让调用者只依赖他需要的那个细粒度函数.
如果把接口理解为OOP中的接口, 也可以理解为面向对象编程语言中的接口语法,那么接口的设计要尽量单一, 不要让接口的实现类和调用者, 依赖不需要的接口函数.
依赖反转原则(DIP)
高层模块不要依赖底层模块, 高层模块和底层模块应该通过抽象来互相依赖. 抽象不要依赖具体实现细节.具体实现细节依赖抽象.
在调用链上, 调用者属于高层, 被调用者属于底层.
控制反转
程序员利用框架进行开发的时候, 只需要往预留扩展点上,添加跟自己业务相关的代码,就可以利用框架来驱动整个程序流程的执行, 控制指的是对程序执行流程的控制,反转指的的是在没有使用框架之前, 程序自己控制整个程序的执行, 在使用框架之后,整个程序的执行流程可以通过框架来控制, 流程的控制权从程序员反转到了框架.
依赖注入
不通过new()的方式在类内部创建依赖对象,而是将依赖对象在外部创建好之后, 通过构造函数,函数参数等方式传递给类使用, 通过依赖注入的方式来将依赖的类对象传递进来, 这样就提高了代码的可扩展性,我们可以灵活的替换依赖的类.
KISS 原则
Keep it Simple and Stupid
尽量保持简单.
如何满足KISS原则
- 不要使用同时可能不懂的技术来实现代码
- 不要重复造轮子,要善于使用已有的工具类.
- 不要过度优化. 不要过度使用一些奇技淫巧(位运算符代替算术运算, 复杂的条件语句代替 if-else,使用过于底层的函数)来优化代码,牺牲代码的可读性
越是能用简单的方法解决复杂的问题,越能体现一个人的能力.
YAGNI 原则
You Ain’t Gonna Need It
你不会需要他.
不要去设计当前用不到的功能, 不要编写当前用不到的代码. 不要过度设计
DRY 原则
Don’t Repeat Yourself
不要写重复的代码.
提高代码复用性
- 减少代码耦合
- 满足单一职责
- 模块化
- 业务与非业务逻辑分离
- 通用代码下沉
- 继承,多态,抽象,封装
- 应用模板等设计模式
迪米特法则(LOD)
高内聚,松耦合
高内聚, 指相近的功能应该放到同一个类中,不相近的功能不要放在同一个类中. 相近的功能往往会被同时修改. 放到同一个类中,修改比较集中, 代码容易维护.
松耦合. 指代码中, 类与类之间的依赖关系简单清晰. 即使两个类由依赖关系. 一个类的代码改动不会或者很少导致依赖类的代码改动.
迪米特法则理论描述
每个模块只应了解那些与他关系密切的模块的. 或者说,每个模块只和自己的朋友说话, 不和陌生人说话.
迪米特法则是希望减少类之间的耦合,让类越独立越好.每个类都应该减少了解系统的其他部分.一旦发生变化.需要了解这一变化的类就会比较少.
在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。 在类的结构设计上,尽量降低类成员的访问权限。 在类的设计上,优先考虑将一个类设置成不变类。 在对其他类的引用上,将引用其他对象的次数降到最低。 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)