提升代码质量的方法:领域模型、设计原则、设计模式(一)

发表于:2021-8-26 09:45

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:阿里云云栖号    来源:今日头条

  一、影响代码差的根因
  1.差代码的体现
  我们可以列举出非常多质量差的代码的表现现象,如名字不知所意、超大类、超大方法、重复代码、代码难懂、代码修改困难……其中最为影响代码质量的两个表现是命名名不副实、逻辑可扩展性差,当一个新人阅读代码时,有时发现方法命名与实际逻辑对不上,这就让人感到非常疑惑,这种现象在平时工作并不少见;另一个就是逻辑扩展性差,一个新业务需求提出来后,发现要在多处改动,需要回归的业务逻辑比较多,造成研发效率不高。
  2.问题归纳
  对第1节中提到的现象进行问题归纳整理,大致整理出6类问题,分别展开加以说明。
  命名问题:命名问题是一件非常头疼的事,想要取一个名副其实又好理解的名字并不那么容易。涉及到变量的命名、方法的命名、类命名,常见的命名问题有两种:一种是不知所云;另一种是名不副实。命名不知所云是一个人初一看,不知道它是什么意思,根本原因就是没有想到一个合适的词汇去抽象问题;命名名不副实是命名和实际逻辑想表达的意思不一样,这样的命名会误导人。
  代码结构问题:当一个人初看工程代码时,当还没有深入看代码逻辑时,从模块划分、类划分、方法划分整体上可以感受得出代码质量,如果一个类有几千行代码,一个方法有几百行,这样的逻辑相信没有多少人愿意去看,复杂度比较高。好的代码层次结构非常清晰,就像看一本优美的书一样有一种赏心悦目的感觉。
  编程范式问题:有三种编程范式:表模式、事务脚本模式和领域设计模式,大家用得最多的是事务脚本模式,这种模式最符合人做事的方法,step by step,这种模式最大的问题就是承担了不该自己承担的职责,看起来比较符合逻辑,实际上问题比较多,平时大家喜欢称之为"面条型代码"。
  可读性问题:代码除了实现业务功能外,还要具备良好的可读性,有的代码没有任何注释;有的代码格式不统一;有的是为了炫耀技术,大段大段的Lambda表达式(并不是说Lambda表达式不好,关键要控制层次深度),这样的代码看起来简洁,可读性并不太好。
  扩展性问题:可扩展性问题是一个老生常谈的问题,要实现良好的可扩展性并不那么容易,一般是没有抽象问题,如店铺在店招头展示Tab,面条型的代码就是直接定义一个List,然后往里面加Tab对象,如果需要再加一个Tab怎么办?典型的就是不满足开闭原则。
  无设计问题:整个代码看起来比较平淡,别人看了之后也从中学习不到内容。一般这种问题是没有深入分析问题,仅仅解决了问题,而没有考虑如何更好地解决问题,比如重复处理流程的工作是否可以抽象成一个通用的模板类、不同处理类是否可以通过工厂类去获取具体的策略、异步处理是否可以使用事件模式去处理、对于新增加的能力能否通过自动注册去发现……
  3.根因分析
  接下来分析下为什么会产生代码差的原因,这个问题有外部原因,也有内部原因。外部原因主要有:项目排期急,没有多少时间去设计;资源短缺,人手不够,只能怎么快怎么来;紧急问题修复,临时方案快速处理……。内部原因主要有:自身技能低,怎么技能没有掌握到,如Lamda表达式、常用的工具类、框架高级用法等;无极致追求的精神,仅仅完成需求就行,稳定性、可扩展性、性能、数据一致性等没有考虑……
  笔者认为最为关键的是内部自身的问题,根因就两个:自我要求不高;无反馈通道。如果对自已要求不高,仅仅满足完成需求开发就止步了,很难写出高质量的代码,另外如果没有外部反馈,也难以提高自己的技能。笔者之前的主管非常严厉,对大家写的代码review比较仔细,一个变量名、一段逻辑的写法,反复让修改,这其实是提升技能最快的方法。
  二、提升代码质量的方法
  提升代码质量的方法,笔者喜欢用三个方法:领域建模、设计原则、设计模式,主要谈下如何使用。
  分析阶段:当拿到一个需求时,先不要着急想着怎么把这个功能实现,这种很容易陷入事务脚本的模式。分析什么呢?需要分析需求的目的是什么、完成该功能需要哪些实体承担,这一步核心是找实体。举个上面进店Tab展示的例子,它有两个关键的实体:导航栏、Tab,其中导航栏里面包含了若干个Tab。
  设计阶段:分析完了有哪些实体后,再分析职责如何分配到具体的实体上,这就要运用一些设计原则去指导,GRASP中提到一些职责分配的原则,感兴趣的同学可以去详细看看。回到上面的例子上,Tab的职责主要有两个:一个是Tab能否展示,这是它自己的职责,如上新Tab展示的逻辑是店铺30天内有上架新商品;另一个职责就是Tab规格信息的构建,也是它自己要负责的。导航栏的职责有两个:一个是接受Tab注册;另一个是展示。职责分配不适理,也就不满足高内聚、低耦合的特征。
  打磨阶段:这个阶段选择合适的模式去实现,大家一看到模式都会理解它是做什么的,比如看到模板类,就会知道处理通用的业务流程,具体变化的部分放在子类中处理。上面的这个例子,用到了2个设计模式:一个是订阅者模式,Tab自动注册的过程;另一个是模板模式,先判断Tab能否展示,然后再构建Tab规格信息,流程虽然简单,也可以抽象出来通用的流程出来,子类只用简单地重写2个方法。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号