《敏捷软件开发》读书笔记(1)

会有一股神秘感。 提交于 2020-01-12 03:03:55

《敏捷软件开发》读书笔记(1)

概述

验收测试

在开始编码之前,可以用需求意图的方式写验收测试。

测试最重要的好处是对于架构和设计的影响。为了一个模块或应用程序可测,必须要对他进行解耦合。

什么是设计

  1. 遵循敏捷实践发现问题

  2. 利用设计原则诊断问题,并且:

  3. 应用适当的设计模式解决问题

设计的坏味道

  1. 僵化性,很难改动,牵一发而动全身

  2. 脆弱性,修改很容易引入问题,而且可能是无关的概念

  3. 牢固性,和某些细节牢牢绑定,很难作为可复用组件

  4. 粘滞性,保持设计比破坏设计做起来更困难麻烦,或者环境很麻烦,一修改就要花很长时间

  5. 不必要的复杂,存在有些不必要的组成,常因为开发人员预测不存在的需求

  6. 不必要的重复,就是重复、类似逻辑的代码了

  7. 晦涩,代码难以理解,不够清晰。

设计原则:

SRP:单一职责

一个类或者组件、模块,只有一个原因让其变化。但是特别要注意,仅当变化实际发生的时候,分离变化才有实际意义,这是敏捷的做法。如果没有变化,那么使用任何原则都是不合适的。

OCP:开放封闭原则

面向对象设计的核心所在,如果一个需求要修改很多地方,比如需要switch语句增加判断分支,就打破了这个原则,而且可能需要依赖这个模块的模块全部重新编译部署。遵循这点设计,需要一定程度预测的策略,或者在发生第一次变化的时候修改为抽象。可以用合适的抽象,或者用数据驱动的方式来获取封闭性(控制代码和逻辑代码分离)。

LSP:里氏替换原则

子类必须能替换基类,而且行为不变,这里关注的是行为。通常用到instanceof的地方,可能就是明显违反这个原则的方式(回想下,我们项目里好多)。这里面提到,对于继承而言,对象的行为才能说明是IS-A的关系,比如正方形和长方形,虽然属性上是,但是行为不是。所以一个设计模型的有效性,不能完全孤立的看,必须要根据使用者做出的合理假设来审视。而合理假设是难以预测的,所以只需要在遇到明显违反LSP的时候再处理。

那么如何能保证子类不违法基类的行为假设呢?可以基于契约设计,基类声明时同时声明前置和后置条件,并且在程序中对其检查,子类保证在复写时,前置条件比基类松,后置条件比基类严。

DIP:依赖倒置原则

让高层模块独立出来,提高复用,framework层的核心设计原则即为如此。优先依赖于抽象的原则,可以让客户类来定义接口,或者单独把通用的接口独立出来,让服务类实现接口,只有客户类需要修改时,才修改接口。关键是要找出系统的内部抽象、高层策略、隐喻、核心逻辑,和具体的形式无关。这个原则是构建可重用框架的必须。

ISP:接口隔离原则

对于客户程序定义接口的时候,按照隔离原则定义,不需要关注到实现类是几个类。容易破坏原则的情况,就是一个实现类继承多个接口类,当接口类扩展时候,会污染实现类,即使在基类统一实现退化接口(比如我们项目里BasePresenter的设计,统一实现了多个接口,这样某一个接口改变的时候,所有的子类都会需要重新编译)。

不应该强迫客户依赖(或者继承)于他们不使用的方法(或者模块),这样在其他客户要求接口修改的时候,就会影响到这个程序,比如换包名,修改接口等,或者修改接口后,会带来其他模块的重新编译,也会减慢编译速度。所以更强调了接口等定义要以使用者为核心,如果是服务者为核心,就会出现服务者修改接口,迫使客户端修改或者重新编译(不过现在Java的模块化或者服务化,只要接口保持向前兼容性,可以用yaml约定接口,客户方使用yaml生成api的方式,解除服务方提供api的耦合,可以独立演进)。

有这么几种方法可以帮助客户程序隔离接口,用委托分离、多重继承(实现)。而客户端依赖的接口,最好使用依赖注入的方式,符合迪米特法则,可以解决客户端程序依赖特定服务版本的问题。

当然,不能说所有的客户端自己定义接口,让服务端被迫实现不同的客户端定义的接口,我们还应该整体上对接口进行分组,同类型功能的接口放在一起(单一职责),公共的方法每个接口都定义。这个也可以是服务端定义接口,但是接口要划分合理,不能全都放在一个类里面。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!