[C#]建造者模式(Builder)

[C#]建造者模式(Builder)

前言

之前筆者有寫過一篇外觀模式,其實建造者模式跟外觀模式幾乎差不多,但目的性不一樣,不過如果我們不管設計模式分類的話,其實對我們來說幾乎目的性是等值的。

想像一下如果我們有一個方法內部使用一堆方法在呼叫,然後有兩個以上的地方都看到相同的邏輯,如果順序有錯誤的話,會導致發生expection或者是算出來數值的錯誤,那就代表了這段程式碼非常需要builder模式,否則工程師一定就是複製貼上的,而這也就是建造者模式適用的場景。

情境模擬

假設我們有一個算匯率價格的程式碼,需要有一連串的呼叫來達成目的,程式碼示例如下

void Main()
{
	var data=GetData();
	var calculatedNumber=Calculate(data);
	var json=ConvertToJson(calculatedNumber);
	SendJson(json);
}

static decimal GetData()
{
	return 20;
}

static decimal Calculate(decimal number)
{
	return number*30;
}

static string ConvertToJson(decimal number)
{
	return "最後匯率為"+number;
}

static void SendJson(string json)
{
	Console.WriteLine($"sales請您確認,{json}");
}

可以看到以上的程式碼其實是有順序性的,我們先假設兩種情況,一種情況是這個呼叫端總共使用了四個方法,如果其中一個方法順序寫錯了位置,可能會導致最後結果不太正常,再來是如果忽然要把json保存進db裡面,那我們如果的順序性就又多了一個方法,當越多需求的時候會安插的方法可能就越多,再者如果這段相同的程式碼出現在很多地方的話,我們只要新增需求,很難避免會漏掉沒改到之類的,所以我們乾脆把這些方法變成一個方法來調用,重構後程式碼如下。

void Main()
{
	SendJson(BuilderCalculate());
}

static string BuilderCalculate()//把多個方法放進Builder裡面
{
	var data = GetData();
	var calculatedNumber = Calculate(data);
	var json = ConvertToJson(calculatedNumber);
	return json;
}

static decimal GetData()
{
	return 20;
}

static decimal Calculate(decimal number)
{
	return number*30;
}

static string ConvertToJson(decimal number)
{
	return "最後匯率為"+number;
}

static void SendJson(string json)
{
	Console.WriteLine($"sales請您確認,{json}");
}

如果我們此時有需求異動,必須要把json的資料存進db,以便以後追查的話,只需要在builder裡面新增就好了,就不會影響到調用端

void Main()
{
	SendJson(BuilderCalculate());
}

static string BuilderCalculate()
{
	var data = GetData();
	var calculatedNumber = Calculate(data);
	var json = ConvertToJson(calculatedNumber);
	SaveJsonToDb(json);//新增了保存到db的部份
	return json;
}

static decimal GetData()
{
	return 20;
}

static decimal Calculate(decimal number)
{
	return number*30;
}

static string ConvertToJson(decimal number)
{
	return "最後匯率為"+number;
}

static void SaveJsonToDb(string json)
{
	Console.WriteLine($"{json}已保存到db");
}

static void SendJson(string json)
{
	Console.WriteLine($"sales請您確認,{json}");
}

最後結果

最後匯率為600已保存到db
sales請您確認,最後匯率為600

結論

其實簡單來說,設計模式有很多部份都很雷同,只是有一點目的性或能達成目的不太一樣,所以難免會覺得這幾個很像,到底要用什麼模式呢?其實對我來說重構程式碼才是最需要學習的部份,只要你常重構那自然就會常常達成某個設計模式,不過筆者其實一直還沒寫過關於測試的文章,畢竟重構跟tdd確實是相輔相成的議題,想寫和想學的太多,以後有時間在把筆者的一些想法分享出來,如果大大覺得筆者論述有誤,再請回覆指導囉。