重构技法

入职新公司,接手已有的项目,重构技能是必须掌握的,这次从基础盘点下常用的重构方法,不深入设计模式。

什么是重构?

在不改变软件逻辑前提下,重新设计并组织代码的行为。

为什么重构?

接手旧项目的时候,以下场景一定不会陌生:

上司交过来的任务,,

拒绝是不可能的嘛....

实际上,远没有答应时的轻松:

代码看了半天还是看不懂啊,一个方法上千行,心累ing

若干天后,终于看懂代码了,但是发现IDE一堆警告,一看提示说存在重复的代码,整个项目都是警告,那么多重复代码,不会封装一下吗!

着优化下代码,改着改着发现好多if-else,还是多层嵌套,每个嵌套的判断还很复杂,想想还是先不改了,万一改出问题,岂不是更糟糕!

脑壳痛...

没办法,只好拿出重构大法,见招拆招!

第一招:重复代码的提炼

重复代码是重构收效最大的手法之一。

好处:代码量大大减少,维护方便,代码条理更加清晰易读。

重点就在于寻找代码当中完成某项子功能的重复代码,将它移动到合适的方法当中,并存放在合适的类当中。

使用泛型提取重复逻辑

 

第二招冗长方法的分割

  往往在我们提炼重复代码的过程中,就不知不觉的完成了对某一个超长方法的分割

 这其中有一点是值得注意的,由于我们在分割一个大方法时,大部分都是针对其中的一些子功能分割,因此我们需要给每一个子功能起一个恰到好处的方法名,方法名要说明此方法的用途,名称无法说明清楚时,才使用注释,这很重要

class GoodExample

{

    public void Method()

    {

        function1();

        function2();

        function3();

    }

    private void Function1()

    {//function[1]

    }

    private void Function2()

    { //function[2]

    }

    private void Function3()

    { //function[3]

    }

}

冗长的函数被分割,重复的逻辑被提取。也就是说函数(接口、类)要职责分明,也就是

单一原则

当方法较多且具有固定流程时,也就是设计模式中的模板方法

第三招:嵌套条件分支的优化

大量的嵌套条件分支是很容易让人望而却步的代码,应该极力避免这种代码的出现

1)将不满足某些条件的情况放在方法前面,并及时跳出方法,以免对后面的判断造成影响。

public void Method(Object A, Object B)

    {

        if (A != null)

        {

            if (B != null)

            {  //code[1]

            }

            else

            {  //code[3]

            }

        }

        else

        { //code[2]

        }

    }

改成这样,好懂多了:

public void Method(Object A, Object B)

    {

        if (A == null)

        { //code[2]

            return;

        }

        if (B == null)

        {//code[3]

            return;

        }

        //code[1]

    }

2)合并分支条件。

        if (A != null)

        {

            if (B != null)

            { //code

            }

        }

改成:

if (A != null && B != null)

 {//code

 }

3)大量分支

当含有大量分支(条件、状态)判断的时候,可以考虑设计模式中的状态模式

第四招:去掉一次性的临时变量

class BadExample

{

    private int increment;

    public void Method(int[] arr)

    {

        int n= arr.Length;

        int temp = GetIncrement();

        for (int i = 0; i < n; i++)

        {

            temp *= i;

        }

    }

}

class GoodExample

{

    private int increment;

    public void Method(int[] arr)

    {

        for (int i = 0; i < arr.Length; i++)

        {

            GetIncrement() *= i;//emm,简洁明了!

        }

    }

}

第五招:消除过长参数列表

将这些参数封装成一个对象传递给方法

class BadExample

{

    public void Method(int i, int j, int k, int l, int m, int n)

    {

        //code

    }

}

改成:

class Data

{

    private int i;

    private int j;

    private int k;

    private int l;

    private int m;

    private int n;

}

class GoodExample

{

    public void Method(Data data)

    {

        //code

    }

}

第六招:提取类或继承体系中的常量

一些字符串常量等,会让人对程序的意图产生迷惑

字符串等类型的常量的消除,方便维护。因为我们只需要修改一个常量,就可以完成对程序中所有使用该常量的代码的修改。

可以使用静态类、结构、字段、枚举...

第七招:优化冗长的类

(1)拆分逻辑可分离的部分

这一步和方法一样,体现了单一原则和高内聚。

(2)让类提供该提供的方法

    public class Data

    {

            public void DataMethod()

            {

               //do something

            }

            public int One{get;}

            public int Two{get;}

            public int Three{get;}

    }

上层可能是这样调用的:

class Program

    {

        static void Main(string[] args)

        {

            GetThree(data);

        }

        public int GetThree(Data data)

        {

            return data.One * data.One * data.One;

        }

    }

我们在上层定义一个方法操纵一个类内部的成员;

这是不应该的,应在类的内部就提供这个方法:

   public class Data

    {

            public void DataMethod()

            {

               //do something

            }

           public int GetThree(Data data)

         {

            return data.One * data.One * data.One;

          }

            public int One{get;}

            public int Two{get;}

            public int Three{get;}

    }

这样在上层只需要调用这个方法即可。

(3)提取重复的成员到父类

这一步是自底向上的设计,当两个类出现相同的成员时,可以抽象出父类或接口,方便以后的扩展。

其他

1、纠正随意命名

无规律的命名让读代码的人头大,,,

2、删除无效注释

精简代码,简短,漂亮

3、约定:

        if语句中的条件表达式的逻辑运算不要超过3

团队合作中,书写约定非常重要,可以大大提升团队开发效率!

通过重构,我们要达到这样的目标:

总结

正在写的项目:重构应该随时进行

      重构通常不是一次性的,它贯穿软件的整个生命周期,只要觉得不合理都是重构的时机

象、继承

的项目梳理既有业务的流程和详细规则,接着梳理技术架构,然后评估方案,就可以重构了~

重构

        让代码更容易理解

       改善内部结构,修改更容易

      提高编程速度,加快业务迭代

经过重构之后:

      (网图侵删)

是不是很形象?

原文地址:https://www.cnblogs.com/Zdelta/p/14122343.html