引子
根据Robert C.Martin在《敏捷软件开发-原则、模式与实践》一书的观点,一个基本满足敏捷开发的代码应该符合以下5个原则:
SRP 单一职责原则
就一个类而言,应该仅有一个引起它变化的原因。
OCP 开放一封闭原则
软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。
LSP Liskov替换原则
子类型必须能够替换掉它们的基类型。
ISP 接口隔离原则
不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。
就一个类而言,应该仅有一个引起它变化的原因。
OCP 开放一封闭原则
软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。
LSP Liskov替换原则
子类型必须能够替换掉它们的基类型。
ISP 接口隔离原则
不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。
DIP 依赖倒置原则
抽象不应该依赖于细节。细节应该依赖于抽象。
但在现实中,由于各个各样的原因,系统中总会有这样那样不符合这5个原则的地方。
抽象不应该依赖于细节。细节应该依赖于抽象。
但在现实中,由于各个各样的原因,系统中总会有这样那样不符合这5个原则的地方。
这样的代码维护起来就两个字: 累 乱。
一个理想的系统,代码层次应该是这样的:
较理想的代码层次和职责
层次 | 职责 | 允许的操作 | 不允许的操作 |
外部入口层(输入入边界) | 接收外部请求,封装成代码内部可用数据 | 读取各种外部输入资源,如http请求,文件等 | 直接调用基础服务 包括直接调用dao,mc,mq等 |
接口服务层 | 校验请求数据的格式合法性,并调度各个业务服务,串联推动业务服务 | 无特殊情况,不直接调用基础服务层 | |
业务服务层 | 进行一个和多个领域模型之间的业务的封装, | 缓存各种独立在db外的信息 可配合工具类实现领域对象的重新封装 | |
领域服务层 | 提供单个领域的各种操作,如增删改查。 | 缓存各种基于db的列表信息 可配合工具类实现领域对象的重新封装 | |
基础服务层 | 提供基础的存储和外部服务依赖的 | dao服务:可对应db行记录缓存领域对象 | dao服务无特殊情况不缓存 领域对象的列表 |