C# -- 幾種常用的代碼重構手法


重構的好處不多敘述了,大家都明白,好的代碼不僅可讀性強,重用性強,而且可維護性高。書上論述的非常詳細,我挑選幾種最常用的重構方法,並用C#語言做示例,總結一下,學習一下!

1:提取函數

原始代碼為:

static void Main(string[] args)
        {
            User user = new User();

            user.name = "張三";

            user.age = 12;

            PrintOwing(user);

            Console.ReadKey();
        }
        public static void PrintOwing(User user) 
        {
            PrintDetail();

            Console.WriteLine("姓名:" + user.name);
            
            Console.WriteLine("年齡:" + user.age);
        }
        private static void PrintDetail() { }

重構為:

static void Main(string[] args)
        {
            User user = new User();

            user.name = "張三";

            user.age = 12;

            PrintOwing(user);

            Console.ReadKey();
        }
        public static void PrintOwing(User user)
        {
            PrintBanner();
            PrintUserInfo(user);
        }
        public static void PrintUserInfo(User user)
        {
            Console.WriteLine("姓名:" + user.name);
            Console.WriteLine("年齡:" + user.age);
        }
        private static void PrintBanner() { }

思想:讓每個函數只做一件事,抽取能夠被組織在一起的代碼,並單獨抽取為一個函數。如果函數的粒度小,被復用的機會就更大。后期如果需求改動,那么需要修改的代碼就很少,可維護性高,同時閱讀起來也不清晰。

2:內聯臨時變量

原始代碼:

double orderInfo = anOrder.BasePrice();
return (orderInfo > 1000);

重構為:

return (anOrder.BasePrice() > 1000);

注意:重構前要保證這個臨時變量只被賦值一次,所以當遇到循環語句時,要注意被內聯的變量的值是否會在循環中被改變。有時在執行循環之前定義固定的臨時變量是必要的。尤其是當臨時變量取自某對象的屬性,而這個對象將在for循環中被更改。

3:以查詢取代臨時變量

原始代碼:

double GetBasePrice = quantity * itemPrice;
if(GetBasePrice > 10)
{
    return GetBasePrice * 9.5;
}
else
{
    return GetBasePrice * 9.8;
}

重構為:

if(GetBasePrice() > 10)
{
    return GetBasePrice() * 16.2;
}
else
{
    return GetBasePrice() * 16.1;
}
...
double GetBasePrice()
{
    return quantity * itemPrice;
}

4:以衛語句嵌套條件表達式

原始代碼:

double GetPayAmount()
{
    double result;
    if(_isDead) result = deadAmount();
    else
    {
        if(_isSeparated)
        {
            result = separatedAmount();
        }
        else
        {
            if(_isRetired)
            {
                result = retiredAmount();
            }
            else
            {
                result = normalPayAmount();
            }
        }
    }
    return result;
}

重構為:

double GetPayAmount()
{
    if(_isDead)
    {
        return deadAmount();
    }
    if(_isSeparated)
    {
        return separatedAmount();
    }
    if(_isRetired)
    {
        return retiredAmount();
    }
    return normalPayAmount();
}

在初學編程的時候,很多人都會寫出很多if…else嵌套的代碼,其實很多時候,else並不是必須的。關於if…else…如何取決,關鍵看你對各分支的重視程度

注:這是在一篇博客里學到的,地址忘記了!

5::引入解釋性變量

原始代碼:

if((platform.ToUpper().IndexOf("MAC") > -1) && (browser.ToUpper().IndexOf("IE") > -1) && wasInitialized() && resize > 0)
{
    //
}

重構為:

bool isMacOs = platform.ToUpper().IndexOf("MAC") > -1;
bool isIE = browser.ToUpper().IndexOf("IE") > -1;
bool wasResized = resize > 0;

if(isMacOs && isIE && wasInitialized() && wasResized)
{
    // do something
}

在某些情況下,表達式可能非常的復雜以至於難以閱讀。這樣,臨時變量可以幫助你將表達式分解為比較容易管理的形式。

6:流程控制語句簡化

原始代碼:

int row = DbHelperSql.ExecuteSql(sql);
if(row> 1)
{
    return true;
}
else
{
    return false;
}

重構為:

int row = DbHelperSql.ExecuteSql(sql);
if(row) > 1
{
    return true;
}
return false;

/////
int row = DbHelperSql.ExecuteSql(sql);
return (row > 1);

return DbHelperSql.ExecuteSql(sql) > 1;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM