11、测试之技术债问题表现及处理方案心得

 

 测试之技术债问题表现及处理方案心得 

一、词语介绍

二、表象

三、造成的结果

四、产生途径

五、优化方案

六、部分词语解释

 

以下资料内容仅供参考,如有不当或者侵权,请联系本人改正或者删除

一、词语介绍

  技术债:技术在开发代码的过程中不注重代码质量,遗留下与技术相关的潜在问题/已存在问题。
 

二、表象

1、类似的代码在不同的项目/产品间迁移
2、相同的问题在不同的模块或者组件中出现
3、某个模块缺陷率不断增加
4、代码已经稳定,但回归测试的成本在增加
5、团队对某个模块或者组件抱怨很难理解或者很难测试
6、每一次交付的成本逐渐增加,新的功能数量增加,引发新的 bug数量持续增加
7、修复 bug的时间越来越长
8、某个模块的源代码频繁被修改
9、系统加载的时间越来越长
10、类似feature 开发的周期开始变长
11、在既有代码上开发,还不如推倒了重来
12、代码实现不合理,引发安全策略问题
13、代码bug触发多种防护措施,击穿策略,影响客户
14、系统缺少设计和及时更新,未知问题和隐藏安全问题多
15、缺少重构系统魄力,延误最佳时机,系统可维护性变差,重构系统风险累积
 
 

三、造成的结果

  技术债:爆发点不可预期、稳定性变差、开发和维护成本上升、挫伤员工积极性等等。
  低质量的代码,会降低后续开发效率,每加一个功能都困难重重,进而拖慢业务进度,后期技术需要不断填坑还债,甚至掩耳盗铃式不处理,让其利滚利,拖延时间越长,还债成本越高,还债意愿越低,业务上的挫败感会给程序员/团队自身带来更大的挫败感,甚至逐渐丧失维护的信心,让其遗忘后成为定时炸弹埋在某个遗忘的角落,直到出现大问题。
或许技术可能有时候想要将代码重构,但承担的风险过大,不敢轻易重构,导致团队使用技术越来越落后,团队/产品竞争力下降。
每每这类问题最严重后果就是导致某个模块或整个系统无法正常支撑当前业务运行的需要,不得不推倒重做,进行重构。几乎每个研发团队,都会经历一次甚至几次的技术重构,来减少技术债。
 
 

四、生的途径

  当今的软件行业,都在追求唯快不破。因为“快”决定着生死,尤其对创业公司而言,每天做的事就是为了生存而战斗。质量是软件在解决生死问题之上的高级需求,同时软件质量没法在直观上被感知。
在大部分的场景中,我们需要先解决生死问题和温饱问题,在这个前提下,可以适当引入技术债、质量债,适当降低质量要求,进行快速试错、快速收集用户的反馈、快速迭代向前。质量是可以被妥协的,质量要求需要先服务于公司所处的阶段和当前的产品战略。
  欠下的债总是要还的,债务叠加,积重难返,最终会导致一个项目的死亡。现在流下的泪,都是当初放过的水。
 
常见的产生原因有以下几点:
1、人员技术水平不足:由于经验缺乏,导致初级开发者编写了质量低劣的代码
2、可持续性差:团队根据当前而非未来进行设计选型,可能暂时解决当前问题,但却拙劣
3、业务不熟悉,设计错误:缺乏优秀/训练有素的设计人员,未遵循设计原则,不懂设计坏味和重构,需求频繁变动。
4、求快不保质量,如期交付压力:求进度,开发者采取草率实践,简单做,下个迭代优化
5、疏忽:在不知情的情况由于缺乏知识和意识而产生;
6、增量:定期不慎产生的而导致增量债务。
7、代码:代码重复、违反静态分析工具和代码异味等;
8、架构设计:设计异味、违反设计规则等、违反架构规则,对非功能性约束认知不足等;
9、质量测试:缺乏测试、测试覆盖面不足和不正确的测试设计等、缺乏稳定性和健壮性的技术验证,QA的自动化不足等;压缩测试时间:压缩测试时间或减少测试,试图以错误的方式可提升速率
10、规范流程:版本控制的模糊,环境参数的混淆等;
11、文档:存在重大问题的文档、缺乏文档和文档过期等

 

 
 

五、优化方案

技术债:技术债,有债必尝,越拖成本越高,最好是在发现的时候马上处理它
管理债务方面:
1、正确认识技术债:(认识、了解技术债构成及影响)
①把技术债务作为技术需求对待,在保证正常交付的情况下分批偿还。
②技术鸿沟和架构债务,越晚修复成本越高,在产品规划过程中应积极做好需求沟通,在特定情况下可考虑通过非功能性迭代完成。
③相关联开发组成员应积极沟通,必要情况下以正式文件形式通知各成员。
 
2、发现并偿还技术债:(有债就还原则、分期偿还、先偿还高息技术债)
①识别代码坏味:找出项目中可改进项
>>代码复杂性、编码风格混乱等可以通过代码分析工具辅助解决。
>>分析改进项

 

 

②消除代码坏味:重写代码,提升代码质量
分期偿还,优先高息技术债
 
 
③运行测试:搭建多维测试体系,提升项目可测试性

 

④提交部署:严格代码审查和谨慎发布,保障项目平滑升级

 

 

 

3、防范技术债积累:
①熟悉系统的业务
②熟悉系统的代码
③挖掘系统存在的技术债
④找到技术债后,做汇总,做评估,做测试
⑤向上级反馈技术债,争取资源去消灭技术债
⑥上线新方案,统计新方案与旧方案的对比,使得个人的价值得到更多的认可
⑦一边做日常工作,一边做技术债的工作,千万不能忘了日常的工作重心陷入天天抱怨系统的技术
 
=========================== 

 部分词语解释

===========================

代码异味/坏味包括:

● 长方法:一个非常长的方法、函数或者过程。
● 巨类:一个非常庞大的类
● 太多的参数:函数或者过程冗长的参数列表使得代码可读性和质量非常差
● 特性依恋:一个类过度的使用另一个类的方法
● 亲密关系: 一个类依赖另一个类的实现细节
● 拒绝继承:子类以一种“拒绝”的态度,覆盖基类中的方法,换句话说就是,子类不想继承父类中的方法。
● 冗余类 : 代码重复或功能相似,或者功能太少的类。
● 人为的复杂:在简单设计已经满足需求的时候,强迫使用极度复杂的设计模式。
● 超长标识符:未按统一命名规则命名导致歧义
● 超短标识符:变量或方法无法通过名称来理解其作用
 
 
 
===========================

设计坏味道包括

7种设计坏味道
1.僵化性: 很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其它改动。
2.脆弱性: 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题。
3.牢固性: 很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。
4.粘滞性: 做正确的事情比做错误的事情要困难。
5.复杂性(不必要的): 设计中包含有不具任何直接好处的基础结构。
6.重复性(不必要的): 设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。
7.晦涩性: 很难阅读、理解。没有很好地表现出意图。
 
11种设计原则
 
----类原则----
 
1.单一职责原则 - Single Responsibility Principle(SRP)-就一个类而言,应该仅有一个引起它变化的原因。(职责即为“变化的原因”。)
 
2.开放-封闭原则 - Open Close Principle(OCP)-软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。(对于扩展是开放的,对于更改是封闭的.关键是抽象.将一个功能的通用部分和实现细节部分清晰的分离开来.开发人员应该仅仅对程序中呈现出频繁变化的那些部分作出抽象.拒绝不成熟的抽象和抽象本身一样重要. )
 
3.里氏替换原则 - Liskov Substitution Principle(LSP)-子类型(subclass)必须能够替换掉它们的基类型(superclass)。
 
4.依赖倒置原则(IoCP) 或 依赖注入原则 - Dependence Inversion Principle(DIP)-抽象不应该依赖于细节。细节应该依赖于抽象。(Hollywood原则: "Don't call us, we'll call you".程序中所有的依赖关系都应该终止于抽象类和接口。针对接口而非实现编程。任何变量都不应该持有一个指向具体类的指针或引用。任何类都不应该从具体类派生。任何方法都不应该覆写他的任何基类中的已经实现了的方法。)
 
5.接口隔离原则(ISP)-不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。(多个面向特定用户的接口胜于一个通用接口。)
 
----包内聚原则----
 
6.重用发布等价原则(REP)-重用的粒度就是发布的粒度。
 
7.共同封闭原则(CCP)-包中的所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中的所有类产生影响,而对于其他的包不造成任何影响。
 
8.共同重用原则(CRP)-一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。(相互之间没有紧密联系的类不应该在同一个包中。)
 
----包耦合原则----
 
9.无环依赖原则(ADP)-在包的依赖关系图中不允许存在环。
 
10.稳定依赖原则(SDP)-朝着稳定的方向进行依赖。应该把封装系统高层设计的软件(比如抽象类)放进稳定的包中,不稳定的包中应该只包含那些很可能会改变的软件(比如具体类)。
 
11.稳定抽象原则(SAP)-包的抽象程度应该和其稳定程度一致。(一个稳定的包应该也是抽象的,一个不稳定的包应该是抽象的. )
 
----其它扩展原则----
 
12.BBP(Black Box Principle)黑盒原则-多用类的聚合,少用类的继承。
 
13.DAP(Default Abstraction Principle)缺省抽象原则-在接口和实现接口的类之间引入一个抽象类,这个类实现了接口的大部分操作.
 
14.IDP(Interface Design Principle)接口设计原则-规划一个接口而不是实现一个接口。
 
15.DCSP(Don't Concrete Supperclass Principle)不要构造具体的超类原则-避免维护具体的超类。
 
16.迪米特法则-一个类只依赖其触手可得的类

原文地址:https://www.cnblogs.com/sulanyuan/p/13890890.html