代码整洁之道

简介: 我们在做系统开发编码时,无论是对于系统响应及时性没有前端系统要求那么高,却有业务复杂、数据严谨的性质。还是面对高并发多线程,海量业务,分布式事务,一致性等要求很高的情况。良好的代码质量是保障系统和业务稳定的基础,要求我们从每一个代码、每一个变量、每一个方法做起

01前言


【挑战者号事件】1986年1月28日,美国东部时间上午11:39,“挑战者”号航天飞机在发射仅  73.124秒后,因右侧固体火箭助推器故障,在1.5万米高空爆炸坠毁,7名航天勇士全部罹难。

ddeee7ffbfc7996543f3c576339de338_640_wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1.jpg


背景:高热气体从出现故障的固体火箭助推器的外壳接缝处泄露出来,喷到外部燃料舱体上,主液氢燃料舱底部发生爆炸,液态氢被点燃。

根本原因:在火箭助推器的圆形接缝处,有2个由合成橡胶制成的同心密封圈。发射前夜,气温降到了-8摄氏度,比密封圈的最低承限温度低了13度,这个温度下的密封圈已经硬的失去了弹性,无法很好地密封高热气体。

工程师们写了备忘录,发出了高危预警信号,要求宇航局的管理人员取消此次发射任务,面对财务和政治的 压力宇航局的管理人员们无动于衷,最终导致此次灾难发生。

反思:事前应对各个零部件进行严格的检测,并将问题报告给生产商莫顿*奥赛科公司和美国宇航局的管理人员,发出预警信号,有必要抗议取消发射任务。如下为发生此次事故的O型圈:

bd305bb6e76ab652b223851f67bf19b2_640_wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1.jpg


02联想(雪崩效应)


由上面的“挑战者号”事故,我们联想到我们作为工程师开发的系统,当由小问题产生的连锁一系列积累也会引起以下问题:


1、服务提供者不可用;


2、重试加大请求流量;


3、服务调用者不可用;


4、整个系统崩溃不可用


2017年做支付系统时,虽然没有遇到灾难性的问题,但是各种问题层出不穷。当时的系统技术栈很落后。


技术栈:Struts1.0、ibatis、jsp/html、ThreadPoolTaskExecutor定时任务。


程序:代码冗余、结构混乱、开发困难、测试部署艰难。


遇到的问题:一个action类2000多行代码,一个method方法几百行代码,上游渠道、支付方式和路由等规则繁多,支付系统处于中台系统,下方连接商家的支付通道接口,上游连接各个银行机构等渠道。没有可视化界面系统部署可以测试和操作,只有一个jsp测试页面用来测试各个接口(交易下单、退款、交易查询、退款查询等)。


查询问题非常艰难,需要去到不同办公司的运维部门同事的机器旁边,登录生产服务器跟踪日志排查问题(或者打包日志自己查询)。经常出现长款或短款问题,商家支付了没有收到支付系统的异步通知,一是由于支付系统问题导致没有通知到商家,二是由于上游渠道问题没有通知到支付系统,或者在接收上游异步通知的过程中出现问题导致失败。


03重构


基于以上频发问题带来的耗费大量运维人员成本和时间成本等,公司决定重构系统。


技术栈:SpringBoot/SpringCloud kafka Redis vue angluar


系统采用微服务架构,按照业务把支付系统划分为:交易、支付、清算、收银台等模块,前后端分离的策略。


开发和测试以及部署工作变得非常简单,采用链路式日志追踪中间,排查问题简单方便,线上问题减少了很多。


重构的微服务子系统架构如图所示:

f360288c4f78bd38f8ebd32efd1502cb_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


04代码整洁之道


4.1 何谓整洁代码

代码逻辑直截了当,缺陷难以隐藏

尽量减少依赖,便于维护,便于阅读

分层战略完善代码逻辑,不冗余

有单元测试,性能调优

只提供一种做一件事的途径

4.2 方法和技巧

有意义的命名

重构

Code Review逐步改进


4.3 有意义的命名

  • a、名副其实
    b、避免误导
    c、做有意义的区分
       变量、函数、参数、类、包命名中的原则
public List<int[]> getThem(){        List<int[]> list1 = new ArrayList<int[]>();  for(int[] x : theList)                 if (x[0] == 4)         list1.add(x);        return list1;    }

以上这段代码,我们认为是不太整洁的,至少存在以下几个问题:

(1)theList中是什么类型的东西?

(2)theList零下标的含义是什么?

(3)值4的意义是什么?

(4)怎么使用返回的列表?

运用整洁的技巧之后:


public List<Cat> getCat(){        List<Cat> catList = new ArrayList<Cat>();            for(Cat cat : animals)      if (cat.color == Constants.WIHTE)                    catList.add(cat);        return catList;    }



05重构


1、何谓重构:软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高可理解性,降低成本。


2、为何重构:可读性差、难以维护和修改,冗余甚至出现隐藏bug,带来线上隐患。重构可以改进这些问题,帮忙找出bug,避免问题。


3、何时重构:《三次法则》第一次做某件事时只管去做 第二次做类似的事会产生反感,但无论如何还是可以去做 第三次再做类似的事,就应该重构了。


预备性重构,让添加新功能更容易;帮助理解重构,使代码更易懂;有计划的重构,长期重构等。


4、挑战:延缓新功能开发,代码所有权,分支问题、测试问题。


尝试重构以下代码段,重构之前:


public void scaleToOneDimension(float desiredDimension, float imageDimension){
        if(Math.abs(desiredDimension - imageDimension) <errorThresold)        return;        float scalingFactor = desiredDimension / imageDimension;        scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);        RenderedOp newImage = ImageUtilities.getScaledImage(image, scalingFactor,scalingFactor);        image.dispose();        System.gc();        image = newImage;}public synchronized void rotate(int degrees){
      RenderedOp newImage = ImageUtilities.getRotatedImage(image, degrees);      image.dispose();      System.gc();      image = newImage;}


重构之后:

public void scaleToOneDimension(float desiredDimension, float imageDimension){
        if(Math.abs(desiredDimension - imageDimension) <errorThresold)        return;        float scalingFactor = desiredDimension / imageDimension;        scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);        replaceImage(ImageUtilities.getScaledImage(image, degrees));}    public synchronized void rotate(int degrees){
        replaceImage(ImageUtilities.getRotatedImage(image, degrees));    }
    public void replaceImage(RenderedOp newImage){
      image.dispose();      System.gc();      image = newImage;    }


06总结


我们在做系统开发编码时,无论是对于系统响应及时性没有前端系统要求那么高,却有业务复杂、数据严谨的性质。还是面对高并发多线程,海量业务,分布式事务,一致性等要求很高的情况。良好的代码质量是保障系统和业务稳定的基础,要求我们从每一个代码、每一个变量、每一个方法做起。


相关文章
|
2月前
技术感悟:代码之道,人生之路
在技术的海洋中航行多年,我深刻体会到,编写代码不仅仅是一项技术活动,更是一种对生活的态度和哲学的体现。每一行代码都蕴含着逻辑、顺序和目的,正如我们的人生旅程一样。通过编码,我们可以创造出无限可能,实现从无到有的过程,这不仅是技术的胜利,更是对生命意义的深刻诠释。本文将分享我的一些技术感悟,探讨编程背后的哲理以及它如何影响我们对世界的认知和理解。
41 8
|
设计模式 数据采集 程序员
代码整洁之道--告别码农,做一个有思想的程序员
代码整洁是软件长期稳定和可扩展的基础,本文作者从现实中的代码、重构、设计模式谈论代码整洁之道,总结出如何做一个有思想的程序员。
131407 58
|
程序员 C++ 开发者
《代码整洁之道》-开篇
《代码整洁之道》-开篇
|
前端开发 测试技术 程序员
《代码整洁之道》-函数
《代码整洁之道》-函数
|
Java 程序员 测试技术
《代码整洁之道》&《程序员的职业素养》
《代码整洁之道》&《程序员的职业素养》
586 0
|
设计模式 测试技术 程序员
代码整洁之道(一)最佳实践小结
Any fool can write code that a computer can understand. Good programmers write code that humans can understand. 普通的工程师堆砌代码,优秀的工程师优雅代码,卓越的工程师简化代码。如何写出优雅整洁易懂的代码是一门学问,也是软件工程实践里重要的一环。前段时间通读了三本经典书籍《代码整洁之道 》、《编写可读代码的艺术》、《重构:改善既有代码的设计》,本文将重点从注释、命名、方法、异常、单元测试等方面总结了一些代码整洁最佳实践。
344 0
|
程序员 容器
代码整洁之道读后理解
###一,关于程序员的价值观 对于一个程序员来说,是应该有价值观的,然而最朴素的基本价值观,就是要写好的代码。然后,要做到这一点不容易, 对些,我针对这些价值观有自己的一些看法: (当然,在网上有关于价值观的内容一大片,各有视角,这里仅仅说说我的看法) 1,good software != quality code 2,软件开本 = 开发成本 + **维护成本** >注
1737 0
|
测试技术 程序员 Perl
代码整洁之道—函数
在编程的早期,系统由程序和子程序组成,后来,在Fortran和PL/1的年代,系统由程序,子程序和函数组成。如今,只有函数存活下来。 函数的规则 短小 函数的第一规则是要短小,第二规则还是要更短小。
|
测试技术 数据库

相关实验场景

更多
下一篇
无影云桌面