美文网首页
好的代码

好的代码

作者: 黄靠谱 | 来源:发表于2019-05-19 18:36 被阅读0次

概述

好的代码就是让人读起来很爽的代码。逻辑清晰,扩展方便,对外封装复杂性。

好的代码,即使写的时候可能不爽,感觉很麻烦(通病):

  1. 但是写只要写一次,读却要被读很多次。
  2. 写的人只有你一个,而且是最了解这个方法的功能,但是看的人会有很多。垃圾代码是只有你自己知道,别人都看不懂。
  3. 写的时候只是痛苦一会儿,而且是理解最深的时候,但是看的可能是几个月,甚至一两年后还有人要看这个代码。垃圾代码,写完过了一个月,自己都不认识了。
    所以:一人受苦,一时受苦,造福自家兄弟们。

好的代码

什么是读起来很爽的代码?

  1. 有注释且清晰
  • 最好的注解是没有注解,取一个准确表达方法功能的名字,这才是最优的注解
  • 为了保证代码的简洁优雅,建议注释统一写在方法上面,不要把代码和注释混杂在一起,除非是特别复杂,或者重点要注意的注释,写在代码里面
   /**
     * 先把老的数据全部逻辑删除,再插入新的信息
     * 更新完 origin的数据之后,再根据 Organization_workday的数据,更新 Organization_hierarchy数据
     *
     */
    @Override
    public Boolean updateOrganizationToWD(String term){
        String category=DataTypeWorkDayEnum.ORGANIZATION.getType();
        int total=hrService.getOrganizationTotalCount();
        if (total == 0){ 
            return false;
        }
        hrLogService.createSyncLog(term, category, total, pullAction);
        organizationRepository.deleteAllOlderOrganizationWDInfoInLogic();
        boolean result=updateLatestOrganization(total, term);
        hrLogService.updateResultLog(category, term, pullAction, result);
        return result;
    }
  • 数据库表的创建注释、字段的注释(包括枚举值)。
    这个是最重要的啊(可以通过 show create table test_sync_log;来查看表结构和注释)
CREATE TABLE `test_sync_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `term` varchar(255) NOT NULL COMMENT '任务批次号',
  `category` varchar(255) DEFAULT '' COMMENT '业务类型: worker、position、profile、organizaition、organizaition_hierarchy',
  `start_time` datetime DEFAULT NULL COMMENT '任务开始时间'
   ...
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='这张表记录 HR数据从...'
  • 废弃不用的表,要么删掉,要么用_bk做后缀啊,误导性太强了。比如position_role_relation_bk
  1. 方法名字一定要能准确表达出该方法的作用,这个误导性也很强,哪怕是花点时间百度翻译一下,也不能为了省事随便取一个名字。或者方法的功能变了,方法名字还是以前的那个。
    比如一个方法 validateParams(User user),那这个方法只能校验参数,不能做任何的写的操作,比如set 比如 remove,要不然太坑爹了。

  2. 主方法的结构一定要简洁清晰,特别是核心的方法。
    不要一个方法堆个几百行甚至上千行,自己看也觉得恶心啊。而且拆分方法的另外一个好处是方便复用。

比如一个新增的方法:适合抽象成3个子方法

  • validateUser()
  • saveUser()
  • 封装返回值

这样写的好处是:

  • 如果我关心程序是如何校验用户的,只需要看第一个方法。
  • 如果我只关心他是怎么存储到数据库的,只需要看第三个方法。
  • 如果我想了解它的返回码是什么意思,那么我只要看第三个方法。
  1. 写一个方便复用的方法
    比如现在有一个根据 身份证号码查询用户姓名的功能,然后mybatis的xml里面多了一个select查询。
    或者update的方法,也可以参考这种写法
    垃圾代码:
select name from user where id_card=#{idCard};

问题:

  • 如果还要返回家庭住址,则要修改这个sql,所以不如写成select * ,因为和数据库交互查询少量数据,查询一个字段和查询多个字段,没有什么差别的
  • 如果要新增一个功能,根据员工工号查询用户信息,或者根据员工邮箱查询用户信息,那么又多了一个写法。
  • 如果扩展之后,一个条件可能包含多条数据,所以用一个list去接返回值这样代码的可扩展性就很强了。整个Mapper文件就很清爽啦
    <select id="find" resultMap="BaseResultMap" parameterType="OrganizationPO">
        select * from organization
        where valid = 1 and available =1
        <if test="name != null" >
            AND name = #{name,jdbcType=VARCHAR}
        </if>
        <if test="corporationId != null" >
            AND corporation_id = #{corporationId,jdbcType=BIGINT}
        </if>
        <if test="parentId != null" >
            AND parent_id = #{parentId,jdbcType=BIGINT}
        </if>
    </select>
  1. 对外开放接口(http接口或者 dubbo接口)一定要对结果值做一层封装
    经常出现的一个业务场景是,调用别人的接口,然后页面报错,返回一坨报错的信息。
  • 第一不安全,可能会导致别人的主流程失败,同时会暴露服务提供方的内部代码信息
  • 第二不友好,人家看到一串报错信息,也不能准确的知道到底是出了什么问题

比如查询用户信息的一个功能,核心的信息是 姓名、邮箱、家庭住址、余额、订单等信息,附属的一个信息是淘宝积分的信息,通过Dubbo接口调用积分系统 获取淘宝积分信息。
如果查询结构未做封装,直接报错,而调用方没有做异常处理,结果整个用户查询的功能就崩溃了。或者即使调用方 try catch了,保住了这个功能可用,但是看到日志中一串报错信息也没有头绪

好的做法是:谁提供服务,谁负责封装调用结果和异常信息的解释

public class ClientBaseResponse<T> implements Serializable {
    private String code;
    private String msg;
    private T data;
}

调用方通过

  • 先check ResponseCode来确定调用是否成功,如果失败则不展示 积分信息,主流程不会崩溃,核心功能仍然可用
  • 如果服务提供方返回码异常,也可以读取 responseMsg,来比较直观的感知到哪里出了问题

另外如果是前端核心地方调取http接口获取数据失败,直接报错导致页面停止渲染的,就非常可怕了,所以好的代码,一定要做好封装

  1. 降低和数据库交互的次数
    比如要新增一个用户,但是必须保证 身份证号码、code、邮箱唯一性,并且返回错误的详细信息。
    辣鸡代码就是
  • 先根据身份证号码查一下,看身份证号码是否重复
  • 再根据code查一下,看code是否重复
  • 再根据邮箱查一下,看邮箱是否重复
    好的代码能结合业务写,辣鸡代码的实现中,不管你新增什么用户,都要先去查3次数据库,才完成检验。但是一般业务场景是用户的信息都是唯一的,极少数情况会重复,所以奔放一点,数据库上面3个字段分别做唯一性索引,然后try catch直接插入,报错的话,再去拼接3个条件做联合or查询。查询返回一个list,遍历这个list,看邮箱、code、身份证号,到底是哪些参数重复了。而不是身份证号码重复了,用户纠正了身份证号码,插入的时候,你又报错code重复了,然后修改完在之后,你又说邮箱冲突,很不友好的一种交互方式。
  1. restful API风格
    真的很棒的一种接口规范。

  2. 枚举是个好东西
    枚举和常量相比:

  • 虽然写起来麻烦一点(好代码的通病),但是读起来很清爽

  • 枚举可以限制某一类型数据的类型,避免错误的枚举值,比如type只能是String,这个常量是做不到的

  • 枚举可以很方便的知道该枚举值有哪些类型,这是常量做不到的,可能不同的枚举值写在不同的代码段上面

  • 枚举值可以附加更多的额外信息,方便使用者了解枚举值

public enum  SignTypeEunm {
    PAPER("PAPER","纸质签名"),
    ELECTRONIC("ELECTRONIC","电子签名");
    private String type;
    private String cName;

    public String getType() {
        return type;
    }

    public String getcName() {
        return cName;
    }

    SignWayEunm(String type, String cName) {
        this.type = type;
        this.cName = cName;
    }

}

相关文章

  • 好的代码

    概述 好的代码就是让人读起来很爽的代码。逻辑清晰,扩展方便,对外封装复杂性。 好的代码,即使写的时候可能不爽,感觉...

  • 好代码

    看到某大神的一篇文章,说在思考怎样才能写出好代码。 我也顺着这个问题思考了一下。 这个问题貌似简单,但是要想说清楚...

  • 《好代码,坏代码》的笔记

    [英] 汤姆·朗 2022-12-16 11:33:16 快速失败指的是确保在尽可能靠近问题实际位置的地方报告错误...

  • MFC好的代码

    判断文件是否存在,并做相应的操作。 获取当前时间 获取最新的ID 文件操作//文件读写操作 移动窗口的位置

  • 什么代码是好代码

    1.可用 当然要完成相应的功能 2.整洁 可读性强,整齐,让人一眼看上去有想读的欲望。或者不至于想读,但是...

  • iOS代码规范 (好代码其实不如“好看”的代码^^)

    编写的公司iOS端代码规范 (已经脱敏了) 注释规范 好的注释可以大大的提高代码的阅读性、也能让自己快速的看懂自己...

  • 阅读记录:《好代码、坏代码》

    最近读了几本有关开发质量的书,有两本都是将质量提升的重点关注到了代码质量本身上。的确,作为软件的最底层的基础基石,...

  • 好的代码会说话-代码整洁之道

    《代码整洁之道》总结 我们需要写出整洁的代码吗 我是个6年开发经验的java程序员,在我的职业生涯中,看到过不少让...

  • 好的开源代码

    使用原生JavaScript制作一个漂亮的音乐播放器【html、css、jq】制作一个简洁的音乐播放器Rythm....

  • 什么是好的代码?

    一句话就是别人容易修改的代码。怎么定义容易修改?如果增加或修改一个功能需要改动很多地方,诸如散弹式的修改,那么这种...

网友评论

      本文标题:好的代码

      本文链接:https://www.haomeiwen.com/subject/xybqzqtx.html