DAY 15
3

## [Day 15]Refactoring - 食神歸位

＠目前的程式碼

``````    public class BlackCat
{
public void Calculate()
{
throw new NotImplementedException();
}

public Product ShipProduct { get; set; }

public string GetsComapanyName()
{
throw new NotImplementedException();
}

public double GetsFee()
{
throw new NotImplementedException();
}
}

public class Hsinchu
{
public void Calculate()
{
throw new NotImplementedException();
}

public Product ShipProduct { get; set; }

public string GetsComapanyName()
{
throw new NotImplementedException();
}

public double GetsFee()
{
throw new NotImplementedException();
}
}

public class PostOffice
{
public void Calculate()
{
throw new NotImplementedException();
}

public Product ShipProduct { get; set; }

public string GetsComapanyName()
{
throw new NotImplementedException();
}

public double GetsFee()
{
throw new NotImplementedException();
}
}
``````

``````    //將各方法內容搬到各個物流商的計算運費方法中

//private void CalculatedByPostOffice()
//{
//    //頁面呈現物流商名稱
//    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();
//    }
//}

//private void CalculatedByHsinchu()
//{
//    //頁面呈現物流商名稱
//    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();
//    }

//}

//private void CalculatedByBlackCat()
//{
//    //頁面呈現物流商名稱
//    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();
//    }
//}
``````

``````        /// <summary>
///GetsComapanyName 的測試
///</summary>
[TestMethod()]
public void GetsComapanyNameTest_v3()
{
BlackCat target = new BlackCat();
string expected = "黑貓";
string actual;
actual = target.GetsComapanyName();
Assert.AreEqual(expected, actual);
}

/// <summary>
///GetsFee 的測試
///</summary>
[TestMethod()]
public void GetsFeeTest_v3()
{
BlackCat target = new BlackCat();
double expected = 0F;
double actual;
actual = target.GetsFee();
Assert.AreEqual(expected, actual);
}

/// <summary>
///Calculate 的測試
///</summary>
[TestMethod()]
public void CalculateTest_v3()
{
//從整合測試的test case，來當做單元測試的test case

//arrange
BlackCat target = new BlackCat()
{
ShipProduct = new Product
{
IsNeedCool = true,
Name = "商品測試1",
Size = new Size
{
Height = 10,
Length = 30,
Width = 20
},
Weight = 10
}
};

//act
target.Calculate();

var expectedName = "黑貓";
var expectedFee = 200;

var actualName = target.GetsComapanyName();
var actualFee = target.GetsFee();

//assert
Assert.AreEqual(expectedName, actualName);
Assert.AreEqual(expectedFee, actualFee);
}

/// <summary>
///Calculate 的測試
///</summary>
[TestMethod()]
public void CalculateTest_v3()
{
Hsinchu target = new Hsinchu()
{
ShipProduct = new Product
{
IsNeedCool = true,
Name = "商品測試1",
Size = new Size
{
Height = 10,
Length = 30,
Width = 20
},
Weight = 10
}
};

//act
target.Calculate();

//assert
var expectedName = "新竹貨運";
var expectedFee = 254.16;

var actualName = target.GetsComapanyName();
var actualFee = target.GetsFee();

//assert
Assert.AreEqual(expectedName, actualName);
Assert.AreEqual(expectedFee, actualFee);
}

/// <summary>
///GetsComapanyName 的測試
///</summary>
[TestMethod()]
public void GetsComapanyNameTest_v3()
{
Hsinchu target = new Hsinchu();
string expected = "新竹貨運";
string actual;
actual = target.GetsComapanyName();
Assert.AreEqual(expected, actual);
}

/// <summary>
///GetsFee 的測試
///</summary>
[TestMethod()]
public void GetsFeeTest_v3()
{
Hsinchu target = new Hsinchu();
double expected = 0F;
double actual;
actual = target.GetsFee();
Assert.AreEqual(expected, actual);
}

/// <summary>
///Calculate 的測試
///</summary>
[TestMethod()]
public void CalculateTest_v3()
{
PostOffice target = new PostOffice()
{
ShipProduct = new Product
{
IsNeedCool = true,
Name = "商品測試1",
Size = new Size
{
Height = 10,
Length = 30,
Width = 20
},
Weight = 10
}
};

//act
target.Calculate();

//assert
var expectedName = "郵局";
var expectedFee = 180;

var actualName = target.GetsComapanyName();
var actualFee = target.GetsFee();

//assert
Assert.AreEqual(expectedName, actualName);
Assert.AreEqual(expectedFee, actualFee);

}

/// <summary>
///GetsFee 的測試
///</summary>
[TestMethod()]
public void GetsFeeTest_v3()
{
PostOffice target = new PostOffice();
double expected = 0F;
double actual;
actual = target.GetsFee();
Assert.AreEqual(expected, actual);
}

/// <summary>
///GetsComapanyName 的測試
///</summary>
[TestMethod()]
public void GetsComapanyNameTest_v3()
{
PostOffice target = new PostOffice();
string expected = "郵局";
string actual;
actual = target.GetsComapanyName();
Assert.AreEqual(expected, actual);
}
``````

＠重構第七式：食神歸位

``````public class BlackCat
{
private double _fee;
private readonly string _companyName = "黑貓";

public Product ShipProduct { get; set; }

public void Calculate()
{
////頁面呈現物流商名稱
//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();
//}

var weight = this.ShipProduct.Weight;

//計算運費邏輯
if (weight > 20)
{
this._fee = 500;
}
else
{
//頁面呈現計算的運費結果
var fee = 100 + weight * 10;
this._fee = fee;
}
}

public string GetsComapanyName()
{
return this._companyName;
}

public double GetsFee()
{
return this._fee;
}
}
``````

＠小結

1. 先滿足使用上的需求
2. 需求也就是測試案例
3. 滿足測試案例也就是測試程式要通過
4. 測試程式通過就代表production code滿足需求。

30天快速上手TDD31

### 2 則留言

0
ted99tw
iT邦高手 1 級 ‧ 2012-10-23 12:01:21

0
pajace2001
iT邦研究生 1 級 ‧ 2012-10-24 12:54:54