[30 days to get started quickly TDD] [Day 9] Refactoring legacy code Description

[30 days to get started quickly TDD] [Day 9] Refactoring legacy code Description


Foreword

Until the previous article, the basic knowledge test required TDD have already come to an end.

Next, you want to practice, it is the reconstruction of the way.

The next few articles will tell you readers friends:

  1. How to find the need to reconstruct parts
  2. How to let the program will speak
  3. To test how combined with the

This article will introduce, how to find a place in the program of reconstruction needs.

The next few reconstruct the way, before the condensed version, see the article: [ASP.NET] reconstruction of the road side story -Refactoring to Patterns, in these articles, we will do a more detailed approach for each inside description and purpose of each step, and can help bring.

situation

We face the system status, which normally means Legacy Code (mentioned Legacy Code, the way we should introduce a good book: Working Effectively with Legacy Code), as shown in the image:

situation

(Source: Source: http:? //Www.chancedia.com/ p = 41470)

Like the ad said the same: "Every Dev likes clean code, but he likes the code dirty."

The purpose of reconstruction

We want to chaotic code, clean and neatly placed where they belong on.

Collated

(Source: http: //jung9572002.pixnet.net/blog/post/1733351-%E6%94%B6%E7%B4%8D%E9%81%94%E4%BA%BA)

Reconstruction Opportunity and

Basically the most suitable time to reconstruct three categories:

  1. Debug完成后
    debug
    (图片来源:http://awards.gettyimages.com/awards.cfm?selCategory=all&display=photographer&workID=67&photographerID=7&photoID=70&sp_sortID=1)
  2. 需求异动
    Demand transaction
    (图片来源:http://www.lykasal.com/2012/10/cats-that-pester-for-food-could-be.html)
  3. 系统有 Bad Smell 的地方
    bad smell
    (图片来源:http://www.thetorontopost.net/2012/09/smell-test-total-fail-for-rob-ford-in.html)

简单的说,就是要修改程序的时候,或是程序很脏的时候,适合重构。

但请记住:“一次只做一件事”

如何找出 Bad Smell

这边的范例,我建立了一个不同物流商会计算出不同运费的网站。

先以 SourceMonitor 为例,来找出系统中复杂度太高的 function ,并将它当做我们重构的目标。( SourceMonitor 的介绍,有兴趣的朋友可以看之前这篇文章:[Tool]SourceMonitor - 程序扫描)

扫描后,按照 Max Complexity 排序,可以看到 Prodcut_v0.aspx.cs ,最大复杂度 14 ,最大深度 5 。如下图所示:

source monitor v0

再点开详细资讯后,可以看到  btnCalculate_Click 这个方法,就是造成最大复杂度与最大深度的原因。如下图所示:

source monitor button click

也可以使用 VS2012/VS2010 的程序度量,来找到复杂度过高的程序,请参考:[Tool]Visual Studio 2010 - 程序度量

接着,来看一下这个 function 的程序,如下所示:


protected void btnCalculate_Click(object sender, EventArgs e)
{
    if (this.IsValid)
    {
        if (this.drpCompany.SelectedValue == "1")
        {
            this.lblCompany.Text = "黑猫";
            var weight = Convert.ToDouble(this.txtProductWeight.Text);
            if (weight > 20)
            {
                this.lblCharge.Text = "500";
            }
            else
            {
                var fee = 100 + weight * 10;
                this.lblCharge.Text = fee.ToString();
            }
        }
        else if (this.drpCompany.SelectedValue == "2")
        {
            this.lblCompany.Text = "新竹货运";
            var length = Convert.ToDouble(this.txtProductLength.Text);
            var width = Convert.ToDouble(this.txtProductWidth.Text);
            var height = Convert.ToDouble(this.txtProductHeight.Text);

            var size = length * width * height;

            //长 x 宽 x 高(公分)x 0.0000353
            if (length > 100 || width > 100 || height > 100)
            {
                this.lblCharge.Text = (size * 0.0000353 * 1100 + 500).ToString();
            }
            else
            {
                this.lblCharge.Text = (size * 0.0000353 * 1200).ToString();
            }
        }
        else if (this.drpCompany.SelectedValue == "3")
        {
            this.lblCompany.Text = "邮局";

            var weight = Convert.ToDouble(this.txtProductWeight.Text);
            var feeByWeight = 80 + weight * 10;

            var length = Convert.ToDouble(this.txtProductLength.Text);
            var width = Convert.ToDouble(this.txtProductWidth.Text);
            var height = Convert.ToDouble(this.txtProductHeight.Text);
            var size = length * width * height;
            var feeBySize = size * 0.0000353 * 1100;

            if (feeByWeight < feeBySize)
            {
                this.lblCharge.Text = feeByWeight.ToString();
            }
            else
            {
                this.lblCharge.Text = feeBySize.ToString();
            }
        }
        else
        {
            var js = "alert('发生不预期错误,请洽系统管理者');location.href='http://tw.yahoo.com/';";
            this.ClientScript.RegisterStartupScript(this.GetType(), "back", js, true);
        }
    }
}

上面就是一陀摊在角落的 code ,一眼望过去,每个字都认识,但却要动脑袋猜测,甚至动手测试才能了解这一段 code 是什么意思。除了难以理解以外,这样巢状 if 的设计方式,健壮性(robustness)上也相当薄弱。

呈现的画面与功能,如下图所示:

UI

小结

要重构之前,得先了解重构的目的、意义,以及如何找到需要重构的程序。

期望重构之后,能对原本可以正常执行的结果完全没有影响,但程序因此具备了更高的可读性、扩充性、健壮性等等...

重构的基本原则是:

  1. 建立测试,确保安全
  2. 由小到大,绝不贪心
  3. 适可而止,绝不偏执

由于重构在 TDD 中,也占了很重要的一个角色,所以希望接下来几篇,可以帮助读者手把手的跟着练习一遍,这样看似简单、又像复杂、又没啥弹性的程序,如何从乱七八糟,变成最后一应俱全的健壮程序。

补充

有读者朋友问到,什么样的程序算的上是 Bad smell ?

这边列出笔者工作环境中的门槛值:

  1. 循环复杂度 > 10
  2. 继承深度 > 3
  3. 区块深度 > 4
  4. 相似程序 > 15行
  5. 综合可维护性指数 < 75

以上,不代表超过标准就一定不好,但就像健康检查报告的指数一样,这些的确是需要被 highlight 出来说明的。

其他静态程序分析的工具与投影片简介,请参考这篇文章:[.NET][Tool]静态程序分析工具简介


或许您会对下列培训课程感兴趣:

  1. 2019/7/27(六)~2019/7/28(日):演化式设计:测试驱动开发与持续重构 第六梯次(中国台北)
  2. 2019/8/16(五)~2019/8/18(日):【C#进阶设计-从重构学会高易用性与高弹性API设计】第二梯次(中国台北)
  3. 2019/9/21(六)~2019/9/22(日):Clean Coder:DI 与 AOP 进阶实战 第二梯次(中国台北)
  4. 2019/10/19(六):【针对遗留代码加入单元测试的艺术】第七梯次(中国台北)
  5. 2019/10/20 (day): [development] Speed ​​eighth echelon (Chinese Taipei)

Would like to receive first-hand information public training courses, or would like to inquire about house training, consulting, coaching, consulting services, please contact Facebook fan page: 91 agile development of the road.

Original: Large column  [30 days to get started quickly TDD] [Day 9] Refactoring legacy code Description


Guess you like

Origin www.cnblogs.com/chinatrump/p/11505525.html