HTML5技术

谈程序的腐化 - rinson

字号+ 作者:H5之家 来源:H5之家 2017-05-11 10:09 我要评论( )

写代码如同打扫屋子,有句话叫一屋不扫何以扫天下。如果单个的一个模块代码都不能管好,如何成就一个完善的软件系统?今天我们来说说,一个代码模块的代码是如何一步步腐化变质,到最后程序员都不愿意去维护它,然后要么重构,要么废弃换新模块的? 代码是有

写代码如同打扫屋子,有句话叫一屋不扫何以扫天下。如果单个的一个模块代码都不能管好,如何成就一个完善的软件系统?今天我们来说说,一个代码模块的代码是如何一步步腐化变质,到最后程序员都不愿意去维护它,然后要么重构,要么废弃换新模块的?

代码是有一定的周期的,这个没有错。为什么有的代码跑上几十年任然好用,而现在互联网公司的很多代码,每年都要做好几次重构?一个成立2年的互联网公司,做一个支付系统,可以做了4-5代,每次重构,这样的代价有多大?如何才能让原有的代码生命周期更加长,而不增加很多的学习维护成本,开发一次使用更久呢?

 

大部分程序员是没有很多机会从0开始搭建一个新程序的,更多的时候是接手别人写的代码。有代码移交还好一点,往往因为各种因素,这些因素你懂的,没有产品文档,没有设计文档,没有程序说明,程序里可能连注释都没有。然后,程序员更新换代又极其的快,互联网时代,程序员在一个公司的平均年资也就1年多,程序就又被传给下一任维护者。很大可能的情况是,最终到你手里的程序各种问题,却能实现基本的功能需求,但代码内部各种问题让程序员总有一个冲动,重构它。

今天不想说重构的问题,而是从根源角度分析,程序为什么会变成这个样子?

 

什么是程序的腐化?

什么是一个软件的质量?一个分类标准是软件外部质量与软件内部质量的统一,外部质量是对外表现是否正常,内部质量是对后续开发有没有坑,就是我在这里说的软件有没有腐化。内部质量标准有:可维护性,灵活性,可移植性,可重用性,可测试性,可理解性(摘录自代码大全)。不符合以上标准都可以称之为代码腐化,形象的理解就是一个苹果,从内部开始烂了,烂到原本应该负责内部代码的程序员拒绝去维护了。

实际的代码腐化的例子:

代码混乱,没有代码规范

不该连数据库的模块连了数据库

模块间的调用混乱:

模块内部的调用混乱,例如C#代码已经使用了EntityFramework,代码中跳过EntityFramework,直接用数据库连接修改数据。

框架与其他不一致,不统一:有的包管理使用gradle管理,有的使用maven。有的后台用.Net,有的用Node,有的用Java。用了HttpClient,又使用Feign去连接其他应用模块

有一些设计前后不一致:有的代码使用了统一的错误定义CommonException,有的用原生的Exception。微服务模块,有resource层接口,定义访问的路径,resource的Impl,service的接口提供具体的数据接口,serviceImpl提供具体数据获取的实现。而在具体编码时,将大量的业务逻辑写入了resource的实现中。

太复杂的抽象不能做方便的变更:一开始设计的Job系统,上面是2-3张图片,下面是动态生成的问题。代码层面对于此设计做了很细致的抽象。突然产品提出了某一个Job的图片有特别,要求显示10张图片,就对抽象的图片部分做了if-else的处理……

无用代码,废弃的接口没有标明

 

代码腐化的原因

没有代码会是init commit的时候就开始腐化的,腐化都是循序渐进的,要一个过程。我总结了一些代码腐化的原因:

没有统一标准,或者没有严格执行
  • 统一标准之代码规范
  • 每个程序员都是有自己的审美的,例如即使是缩进长度这种代码里不影响任何功能的东西,有的喜欢空4格,有的喜欢2格。有的喜欢黑色的编程背景,有的喜欢白色的编程背景。有的喜欢if后直接跟上左括号,有的就喜欢另起一行。

    代码规范还是要有的,包含各种格式定义,大小写规范,命名规范等。前端有各种lint工具(jslint,tslint)可以帮助规范,后台的ide也有一些方法帮助。像Baidu,Google这样的公司还有构建时的自开发的检查工具,所以常常一个资深程序员第一次开发的代码要花上1-2天才能提交通过。

    代码规范的混乱,直接导致代码可读性的降低。可读性直接影响后续的生产力。一个程序员天天对着看不顺眼的代码,怎么可能高效?

  • 统一标准之基础规范
  • 除了代码规范外,项目命名,通讯方式,基本的程序框架,后端Java的springboot,sprintMVC,前端的angular,vue,react等都需要统一,还有统一的基础环境(eureka,elk,redis,apigateway等)。

    不统一的后果是各种部署,管理,编码的低效。例如搭一个jenkins,然后部署服务A用的Maven,服务B用的gradle,就导致编译代码写2套,如果写一套基本一样的,当然会快一些。

     

    我统计的java代码中可以统一的部分(包含但不限于)

    Http调用格式,统一用content-type:application/json,response也统一要求这样。

    HttpClient的标准化

    框架,如SpringBoot

    项目管理工具:Maven,Gradle

    项目的CI,CD

    配置管理模式,例如统一成一个配置文件application.properties

    环境变量配置方式,qa,stag,prod。不要有的人写stage,staging,也不要写成production等等细节

    代码基础结构:例如标准的maven目录的结构

     

    项目命名方式:

    com.(公司名).(开发组名).(系统名).(模块名)

    例如:com.omniprimeinc.cosmetic.application.server;

    Restful接口设计统一:大小写,命名方式,Body的最大大小

    例如,Post接口是否可以加PathParameter和QueryParameter。Post接口是否可以不带Body。

    其他配套功能的统一性:调用链,动态配置管理,缓存,分布式事物

    数据库的统一:统一数据库,数据库版本,是否可以使用存储过程等。关于数据库统一性不在这里展开,这点也非常的重要。

  • 统一规范之公司统一框架
  • 刚才说的统一,很多是从公司层面的统一,如果大家都只用springboot,都沿用统一的后端框架,前端统一用angular。那么这个时候,为了方便统一,就需要有代码相关的脚手架工具,直接生成基本的统一项。这样一个工具的好处是可以直接一键完成许多基础工作,并完成了底层的统一工作。

     

    多头维护

    代码腐化的一个很重要的因素是多头维护,甚至是多代维护。

    一个公共项目,多个开发团队都在维护,那就很难统一标准。初始版本有一个架构,然后换了一个架构,开发更是换了几批。人多手杂说的就是这样的情况。

    任何开发团队接手一个旧项目时,其实都是有学习和适应的成本的。频繁的变更开发人员带来的坏处就是反复的人为制造这个成本,其次就是有几率丢失之前的一部分标准和架构规划。

     

    架构没有落地

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 和真正的程序员在一起是怎样的体验 - 静儿1986

      和真正的程序员在一起是怎样的体验 - 静儿1986

      2017-05-10 18:03

    • 其实我就是想好好的写写代码(一个伪程序猿的独白) - 坚持的孤独

      其实我就是想好好的写写代码(一个伪程序猿的独白) - 坚持的孤独

      2017-05-09 15:00

    • 做个程序媛也挺好 - QISHUANG

      做个程序媛也挺好 - QISHUANG

      2017-05-07 11:00

    • 一个想法照进现实-《IT连》创业项目:创业时该不该用新手程序员 - 路过秋天

      一个想法照进现实-《IT连》创业项目:创业时该不该用新手程序员 - 路

      2017-05-06 15:01

    网友点评
    s