[SCRUM]论程序腐败

>>[SCRUM]论程序腐败

[SCRUM]论程序腐败

写代码就像打扫房子一样,有一个词说房子不能打扫世界。如果单个模块不能很好地管理,那么如何完成一个完美的软件系统呢?今天我们将讨论代码模块的代码是如何逐步被破坏的,直到最后,程序员不愿意维护它,然后重新构建或放弃新模块。
代码有一定的时间,这并没有错。为什么有些代码会运行几十年,现在许多互联网公司的代码现在必须每年重组几次呢?一个2年的互联网公司,一个支付系统,可以做4-5代,每次重新配置,价格是多少?如何使原始代码的生命周期更长,而不增加学习和维护的成本,以及如何在更长的时间内使用它?
大多数程序员没有很多机会从0开始一个新的程序,更多的时间是接管别人编写的代码。代码传递是一件好事,往往是因为各种因素,那些因素你知道,没有产品文档,没有设计文档,没有程序描述,程序中可能没有注释。然后,程序员正在迅速升级。在互联网时代,一个公司的程序员平均年龄超过1岁,程序被传送给下一个维护者。最有可能的情况是,最终遇到的各种问题都能实现基本的功能需求,但是代码内部的各种问题使程序员总是有一种重构的冲动。
我们不想说今天的重构问题,但是从根本上看,为什么程序看起来像这样?

这个节目的腐败是什么?

软件的质量是什么?分类标准是软件的外部质量与软件质量的统一。外部质量是否是外部性能是正常的,内部质量是否是后续发展的关键是我所说的软件是否已经损坏了。内部的质量标准是:可维护性、可移植性、可重用性、灵活性、可测试性和可理解性(从代码书节选)。不符合上述标准可以称为代码损坏。图像理解是一个从内部开始腐烂的苹果,对负责内部代码的程序员来说是糟糕的,并且拒绝维护它。

代码腐败的实例:

代码混乱,没有代码规范
甚至连数据库模块都没有连接到数据库。
模块之间的调用是混乱的:
该模块内部调用是混沌的,例如,C #代码已经使用EntityFramework代码跳过EntityFramework,并修改数据直接与数据库连接。
该框架是与他人,不一致的不一致:一些软件包管理工具的管理使用,有的使用Maven。一些后台使用.NET,一些节点,一些使用java。使用HttpClient,用假装连接其他应用模块
有些设计是不一致的:一些代码使用一个统一的错误定义commonexception,和一些使用原生异常。微服务模块具有资源层接口,定义访问路径。对资源和服务接口的实现提供了具体的数据接口。serviceimpl提供具体数据采集的实现。在特定的编码中,大量的业务逻辑被写入资源的实现中。
过于复杂的抽象无法进行方便的更改:第一个设计的作业系统有2-3张图片,下面是动态生成问题。代码级抽象地为这个设计抽象。突然,该产品提出了一个工作的特殊图片,要求显示10幅图片,并做其他的抽象图片部分…
无用代码,未使用的接口未标记

代码损坏的原因

当代码开始衰减时,init不会提交任何代码,而腐败是渐进的,也是一个过程。我总结了一些代码损坏的原因:

没有统一的标准,也没有严格执行。

  • 统一标准代码规范
每个程序员都有自己的审美观。例如,即使缩进长度不影响代码的任何功能,有些像空的4个正方形,有些像2个网格。有些像黑色编程的背景,有些像白色编程的背景。有些人喜欢跟着左括号后面的if,有些喜欢玩另一行。
代码规范仍然可用,包括各种格式定义、大小写规范、命名规范等。有各种各样的皮棉工具(JSLint,tslint)在前端,有助于规范,和背景的IDE也有一定的帮助。像百度和谷歌这样的公司在施工时也有自己开发的检测工具,所以资深程序员通常需要1-2天的时间来提交。
代码规范的混乱直接导致了代码可读性的降低。可读性直接影响后续的生产率。程序员怎么能每天看着讨厌的代码,怎么能高效呢?
  • 统一标准的基本标准
此外,代码规范,项目命名、沟通模式、基本程序框架,springboot,sprintmvc,角,Vue,反应后端java都需要统一,以及统一的基本环境(尤里卡,麋鹿,redis,apigateway,等)。
不统一的后果是各种部署、管理和编码效率低下。例如,建立一个詹金斯,然后部署用于服务的专家,服务B的摇篮,将导致2套编译代码,如果你写的一套基本的,当然,它会更快。
我能数的java代码统一的部分(包括但不限于)
HTTP调用格式,内容类型的统一使用:应用程序/ JSON,响应也统一要求。
标准化的HttpClient
框架,如SpringBoot
项目管理工具:Maven,Gradle
项目的光盘
例如配置管理模式,统一为一个配置文件application.properties
环境变量配置、QA、雄鹿、产品不写阶段,分期,不要写生产等。
代码基础设施:例如,一个标准的Maven目录结构
谈程序的腐化

项目命名方式:
com.(公司名).(开发组名).(系统名).(模块名)
例如:com.omniprimeinc.cosmetic.application.server;
Restful接口设计统一:大小写,命名方式,Body的最大大小
例如,Post接口是否可以加PathParameter和QueryParameter。Post接口是否可以不带Body。
其他配套功能的统一性:调用链,动态配置管理,缓存,分布式事物
数据库的统一:统一数据库,数据库版本,是否可以使用存储过程等。关于数据库统一性不在这里展开,这点也非常的重要。
  • 统一企业框架的统一框架
刚才说的统一,很多是从公司层面的统一,如果大家都只用springboot,都沿用统一的后端框架,前端统一用angular。那么这个时候,为了方便统一,就需要有代码相关的脚手架工具,直接生成基本的统一项。这样一个工具的好处是可以直接一键完成许多基础工作,并完成了底层的统一工作。

多头维护

代码腐化的一个很重要的因素是多头维护,甚至是多代维护。
一个公共项目,多个开发团队都在维护,那就很难统一标准。初始版本有一个架构,然后换了一个架构,开发更是换了几批。人多手杂说的就是这样的情况。
任何开发团队接手一个旧项目时,其实都是有学习和适应的成本的。频繁的变更开发人员带来的坏处就是反复的人为制造这个成本,其次就是有几率丢失之前的一部分标准和架构规划。

架构没有落地

代码模块的功能设计规划,制定的标准,没有详细的落地。架构定了一套,开发没有严格执行。每天写代码这么忙,架构只管架构,不管细节。开发每天撸代码,只管功能,不管架构和代码质量(这个质量不是指功能实现上的质量,而是说严格执行各项统一标准的程度)。甚至说,一个高层服务,不能调用同级服务,只能调用底层服务。因为开发的没有严格执行,甚至加了数据库连接,直接去取了数据库,这样的事一旦开了口子,就像黄河决堤,不可收拾了。
所以,以上说的是架构的落地落实很重要,让所有具体的开发参与者落实同一个标准。架构就需要落实相关的设计,相关的文档,相应的执行检查。现实的情况从来没有靠文档解决一切问题的,可它能解决80%的问题,另外就尽量减少开发人员的变动,以减小换人带来的代码腐化问题。

防止代码腐化的建议:

代码规范标准化,统一化治理

代码的内部质量其实很难保证,规范执行也更多的靠人治,甚至个别标准化的东西,只能通过代码层面去检验,无法通过测试或其他手段进行。
另外,虽然有一些通行的默认标准,更多的标准是代码的负责人自行确定的标准,完全根据喜好来,就像前面说的缩进的长度。好比是老妈和丈母娘都跑来你家里帮你打扫卫生,老妈喜欢把厨房里的锅都一路洗好挂起来,丈母娘喜欢找一个橱柜,都放在橱柜里,你能怎么办?没关系,只要确定下一套标准,不要经常改就好了。

架构严格落地

像前面说的标准,特别是自定义的标准,都需要落地。第一优先文档,第二是团队内部达成共识,第三是执行。

严格的codereview

防代码的腐化执行是一个关键点,这个关键点就是codereview。在这个时间点,再次与开发强调标准的重要性,让开发知晓执行,让测试监督,让架构严格检查。对于不符合的,开发要再次去学习执行标准。

减少开发人员的变动

如果一个团队内,原本标准就是统一的,团队内实行敏捷开发,任何一个开发都可以替代其他开发工作,那么两个人交换任务就没有问题。如果团队内都不统一,这个变动就会严重影响开发,代码腐化的可能会变的很大。
而团队间,标准统一的可能性比在团队内更难,要避免团队间的项目移交才是最优的方法。

代码模块架构Keep it Simple&Stupid,使用一眼就明白的架构

现实世界中,业务需求永远的跑在技术需求前面,很可能架构相关的设计没有文档,没有说明,一旦架构师不在,原来的开发换人了,导致原先的标准和设计无法继续下去,一旦有交接,标准的丢失和架构的变化不可避免。这时,此条原则就能发挥作用。要使用傻瓜化的架构,就是任何一个新来的程序员,一眼就能看明白的架构。例如使用公司统一的项目代码生成器,脚手架,生成统一的代码结构,不需要程序员再投入代码结构学习的成本。而且通用架构就意味着,后续的架构师接受原先设计的可能性大增。
谈程序的腐化

分层的概念很早就提出来了,为什么MVC的概念会这么受欢迎?我觉得是因为它足够傻瓜化。数据库的架构结构中,定义repository,service接口,serviceImpl的实现等也成为了很通用性的设计。
有一个挺经典的例子就是asp.net.MVC的程序组织架构
三个文件夹:Controllers,Models,Views直接约定,并强调约定大于配置。只要是开发过这类程序的程序员,都知道从Controller看路径和RestApi入口,Models看数据结构,View看Html视图。就不需要额外的学习成本。
Maven的标准目录结构也是一个例子。(见上图)

定期清理维护

如同像打扫房间一样,一段时间不打扫,自然会有边边角角的脏东西出来。那么有没有定期的去清理呢?还是不管他,每次看到地上的一团纸,都绕过,而不是去扔了?
定期的清理维护不单是一个维护代码的过程,更是一个重新梳理和统一标准的过程,让现有的开发和架构,再次的达成一致,以提高战斗力

防止代码膨胀

微服务概念的提出后,很好的解决了一个问题,我们的一个代码模块应该写多少大的问题?一个模糊的建议是一个Sprint能重写的大小,如果更大,就应该要差分。有时候代码的清理维护工作也要以这个原则来处理,不能出现过大的代码模块。因为过大的代码模块,首先带来的是程序的复杂度,让程序员理解起来要更多成本。其次,模块内部的耦合度必然也提高了,增加了难度。这时,需要的是切分出一个新模块出来。

总结

代码腐化是程序开发的一个经典问题。代码内部质量的降低,外部质量确可以被客户接受。程序员经常想着,等业务没那么忙的时候,做点清理,做点模块局部的微重构,我的经验告诉你,这些都是假的。如果定下了定期清理,定期检查拆分,就必须立马去做。做这些事的优先级要远高于业务需求。
为什么呢?想象一个程序C++的printf,里面的代码写的非常的烂,变量命名都是p,m,k完全不能直观理解含义,我们需要郑重的去处理这个模块的代码腐化问题吗?其实不需要,因为printf模块的代码需求,就是把输入的内容打印出来,永远都是这样,没有任何新需求,没有新需求就代表没有程序员需要深入内部去改它的代码,不需要改的代码,我们是没有动力去解决它的腐化问题的。有必要经常深入解决腐化问题的代码,必然是业务需求很多,经常要变更的代码。不要等到它已经腐化到代码生命周期都快走到头了,才想起来去维护清理它,要经常维修一下,才能更好的让它发挥作用,是吧?一辆不打算开的老爷车,发动机坏了就坏了,一辆经常开的二手奔驰,定期维护少不了。

文章从互联网整理而来,旨在传播SCRUM、研发项目管理、敏捷开发管理工具的知识与应用,帮助软件开发企业真正了解SCRUM的价值和意义,如果本文侵犯了您的权益或者您需要具体了解更多国内做研发项目管理系统的公司翼发云敏捷项目管理系统的相关信息,欢迎和我们联络:

【网址】www.effapp.com

2018-04-23T04:47:40+08:002018-04-23 04:47:40|Categories: scrum项目管理|