设计原则

设计原则的逻辑

设计原则是指导设计的经验总结,设计模式是问题导向的一系列方案或者设计思路,编码规范是实现可读性的约束手段。通过设计原则的指导,使用设计模式,经过编码规范约束并配合重构,保证代码的可读性、扩展性、可复用性,最终实现高内聚、低耦合的模块或系统

以下的原则并非都是正交的,各个原则之间甚至还有可能冲突,这就要求我们必须找到一个合适的点,合理利用这些原则。同时,这些原则也并非金科玉律,每条原则都有其所适用的范围,记住,软件工程没有银弹。

SOLID设计原则

SRP:单一职责原则

任何一个软件模块都应只对某一类行为负责,修改一个类的原因应该只有一个

主要讨论的是函数与类的关系,当这个类需要做过多事情的时候,也就是出现了很多不相关的函数时,就需要分解这个类

OCP:开闭原则

设计良好的软件应该容易扩展,而禁止修改

该原则要求在添加新功能时不需要修改代码。但是这条原则真的很容易做到吗?在繁杂的业务代码中,大部分情况下,业务发生变更,业务代码必须要进行修改。这就要求我们编写的代码可以适应未来的情况,可根据需求软编码的方式来变更业务逻辑。

依赖方向的控制

通过接口来反转组件之间的依赖关系,使得高阶组件不会因低阶组件被修改而受到影响

信息隐藏

通过中间层使高层组件不过度依赖低层组件的内部细节

LSP:里氏替换原则

一个软件实体如果使用的是一个基类的话,那么它一定也可以使用其子类,而且它根本不能察觉出基类对象和子类对象的区别

animal.run();// ↓cat.run();

如果不满足这个原则,那么各个子类的行为上就会有很大差异,增加继承体系的复杂度

ISP:接口隔离原则

对模块来说,跟它无关的接口一旦发生变更,应该不能影响到该模块,不应该强迫客户依赖于它们不用的方法

使用多个专门的接口比使用单一的总接口要好

DIP:依赖反转原则

高层模块不应该依赖于低层模块,二者都应该依赖于抽象抽象不应该依赖于细节,细节应该依赖于抽象。

当然某些情况下抽象必须依赖于细节,比如Object中对String的依赖

想要设计一个灵活的系统,则就应多引用抽象类型,而非具体实现。这么做的原因是接口相比实现更为稳定

主要关注的是系统中那些经常变动的

组合聚合原则

继承体系中 父类的变化也会影响到子类 所以能用组合聚合就不要用继承

DRY dont repat youself

如果多次遇到同样的问题,就应该抽象出一个共同的解决方法,不要重复开发同样的功能

  1. 完全相同
  2. 算法相同

违反这个原则常被称为WET(Write everything twice)

YAGNI you ain't gonna need it

指的是你自以为有用的功能,实际上都是用不到的。不要考虑的过于长远

要在设计里规划,不要在代码体现

某种程度上来说,这个原则跟DRY有一定的冲突

Rule of Three

是DRY和YAGNI的折中之道。计算机科学中,最常见的就是做取舍了。

KISS keep it simple and stupid

保持简单。并非指实现上的简单,更多地是指让产品(代码)给用户用起来感觉很简单。

POLA 最小惊奇原则