重构、编程规范

目录

一,函数重构方法

1,条件合并

2,变量排查

3,圈复杂度计算

4,超多case的switch语句

二,重构:改善既有代码的设计

1,重构的原则

2,代码坏味道

3,构筑测试体系

4,重构方法

三,编程规范

1,调用函数时前面为什么要加(void)


一,函数重构方法

1,条件合并

最近在重构函数,要求圈复杂度不超过7。

遇到这么一种代码:

if (A && B && C) {
    do {
        sth1;
    }
}
if (B && C) {
    do {
        sth2;
    }
}

我改成了

if (B && C) {
    if (A) {
        do {
            sth1;
        }
    }
    do {
        sth2;
    }
}

圈复杂度直接降低2

2,变量排查

 拆分函数的时候,对于拆出来得到的新函数,

要看里面的所有变量是什么类型的变量,是否有定义。

按照变量所写的位置,分为几种:

普通变量、数组下标变量、小数点或->后面的变量、宏里面的变量,

当然,宏里面的变量也分为普通变量、数组下标变量、小数点或->后面的变量,

对于小数点或->后面的变量可以不用管,对于普通变量、数组下标变量,需要注意是否有定义。

如果是全局变量或宏定义的常量,那就是有定义,如果没有定义,那就有2种处理方式:

要么传参,要么直接在新函数中定义。

传参是为了传值进来或者传值出去,而有的临时变量,既不会传入,也不会传出,就不用传参。

临时变量的生命周期拆分:

有的函数是这么写的:

    int x;
    x=fun1();
    y=f(x);
    x=fun2();
    z=f(x);

如果要把这个代码拆成2个函数,对于x这个变量,其实是可以拆开的,也就是说,上述代码等价于

    int x;
    x=fun1();
    y=f(x);
    int xxx
    xxx=fun2();
    z=f(xxx);

这样,拆开成2个函数之后,就不用把第一个函数计算出来的x的值传到第二个函数。

总结:

(1)注意读宏

(2)小数点或->后面的变量可以不用管,全局变量或者宏定义的常量也不用管,宏里面的变量和其他变量要么传参,要么直接在新函数中定义。

(3)传参是为了传值进来或者传值出去,而有的临时变量,既不会传入,也不会传出,就不用传参。

(4)形如上述的代码中,临时变量的生命周期可拆分,避免冗余的参数传递。

3,圈复杂度计算

我司系统计算的圈复杂度,貌似是这个逻辑:

起步是1,然后if算1个,else算1个,如果是else if只算1个,

case算1个,default算1个,空case不算,空default算。

这个计算逻辑,和我想象中差别挺大的。

更新:

switch语句的圈复杂度计算方法应该是,有多少个break就算多少个。

4,超多case的switch语句

如果一个switch有case1,case2......case20,

首先确认下有没有哪个case修改了枚举值,原则上case语句不应该修改枚举值的,不过还是要以防万一。

再确认下是不是所有非空case都带了break,如果有case不带break,那么这个case执行之后还要执行default语句。

如果没有case修改枚举值,而且,所有非空case都带了break或者default语句是空的,那么所有case可独立判断执行,也就是说可以以任意组合方式拆开成若干个switch语句,任意顺序排序。

二,重构:改善既有代码的设计

1,重构的原则

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

为何重构:重构改进软件的设计,重构使软件更容易理解,重构帮助找到BUG,重构提高编程速度。

何时重构:事不过三,三则重构。

2,代码坏味道

神秘命名、重复代码、过长函数、过长参数列表、全局数据、可变数据、发散式变化、霰弹式修改、依恋情结、数据泥团、基本类型偏执、重复switch、循环语句、冗赘的元素、夸夸其谈通用性、临时字段、过长的消息链、中间人、内幕交易、过大的类、异曲同工的类、纯数据类、被拒绝的遗赠、注释

3,构筑测试体系

先写测试用例,现有代码测试通过,然后再重构,小步快跑,每跑一步就可以测一下。

4,重构方法

  • 常用手法:提炼函数、内联函数、提炼变量、内联变量、改变函数声明、封装变量、变量改名、引入参数对象、函数组合成类、函数组合成变换、拆分阶段。
  • 封装:封装记录、封装集合、以对象取代类型、以查询取代临时变量、提炼类、内联类、隐藏委托关系、移除中间人、替换算法
  • 搬移特性:搬移函数、搬移字段、搬移语句到函数、搬移语句到调用者、以函数调用取代内联代码、移动语句、拆分循环、以管道取代循环、移除死代码
  • 重新组织数据:拆分变量、字段改名、以查询取代派生变量、将引用对象改为值对象、将值对象改为引用对象
  • 简化条件逻辑:分解条件表达式、合并条件表达式、以卫语句取代嵌套条件表达式、以多态取代条件表达式(提炼函数)、引入特例、引入断言
  • 重构API
  • 处理继承关系

三,编程规范

1,调用函数时前面为什么要加(void)

调用函数时前面加(void),是为了显式指明,程序不处理函数返回值。

这是一种较好的编程规范,增加可读性之类的好处。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值