文藝復興的畫室接委託案,客戶上門通常不會空手講幾句就走
畫多大、畫誰、用什麼背景、木板還是畫布、要不要鑲金、什麼時候要
每一項都得講清楚
講一次可能還好
但如果每一次跟畫室的人溝通,都要把這七八項條件重新覆誦一遍,講到第五次,順序就開始亂了
Day 05 留了一個尾巴:
private decimal CalculatePrice(Product product, int qty, CustomerTier tier, string couponCode)
四個參數,勉強還讀得出來
但真正該被拿出來鞭的,是 Process 本人
回頭看 Day 01 一路傳承下來的簽名:
七個參數,看了頭就開始痛了
public decimal Process(int customerId, int productId, int qty,
string customerType, string couponCode, bool sendEmail, bool sendSms)
實際呼叫這個方法,長這樣:
processor.Process(1001, 2002, 3, "VIP", "WELCOME10", true, false);
這一行,沒有人看得懂
1001 是客戶編號還是商品編號?true 是要發 email,還是要發簡訊?false 又是哪一個?想確定答案,只有一個辦法:跳回方法定義,從頭數第幾個參數對應第幾個位置
這跟背誦咒語的順序,沒有本質上的差別
背錯一個字,結果完全不同,而且編譯器不會提醒你
兩個相鄰的 bool 參數,sendEmail 和 sendSms,順序一旦調換傳錯
程式照樣能編譯、能執行,只是簡訊變成信件,信件變成簡訊,沒有任何錯誤訊息告訴你哪裡不對
沒有人一開始就想寫七個參數的方法
過程通常是這樣:
Process(customerId, productId, qty),三個參數,很乾淨customerType
couponCode
bool,一個管 email、一個管簡訊每一次加一個,理由都很合理
加總起來,變成一句要背誦七個位置的咒語
畫室後來想通了:與其每次口頭覆誦七八項條件,不如做一張「委託單」,把所有規格寫在上面
客戶只要填好單子交過去,畫室要用哪個欄位,自己去單子上找,不必再靠記順序
換成程式碼,這是引入參數物件 (Introduce Parameter Object):
public record OrderRequest
{
public int CustomerId { get; init; }
public int ProductId { get; init; }
public int Qty { get; init; }
public CustomerTier Tier { get; init; }
public string CouponCode { get; init; }
public bool SendEmail { get; init; }
public bool SendSms { get; init; }
}
Process 的簽名,變成只接收一張「委託單」:
public decimal Process(OrderRequest request)
{
var (customer, product) = LoadAndValidate(request.CustomerId, request.ProductId, request.Qty);
decimal price = CalculatePrice(product, request.Qty, request.Tier, request.CouponCode);
DeductStock(product, request.Qty);
LogOrder(request.CustomerId, request.ProductId, request.Qty, price);
NotifyCustomer(customer, request.SendEmail, request.SendSms);
return price;
}
呼叫端變成:
processor.Process(new OrderRequest
{
CustomerId = 1001,
ProductId = 2002,
Qty = 3,
Tier = CustomerTier.Vip,
CouponCode = "WELCOME10",
SendEmail = true,
SendSms = false
});
每個值都掛著自己的名字,不必再靠位置背誦。
半年後想加一個「是否要開發票」,只要在 OrderRequest 多一個屬性Process 的簽名完全不用改,所有呼叫端也不用跟著改
參數多,不一定都要立刻包成物件。判斷的重點是:
bool)?只要答案讓你猶豫,這個方法大概已經在念咒語了
OrderRequest 裡的 CustomerId、ProductId、Qty,看起來已經很乾淨了
但如果你去翻其他方法,會發現這三個值,總是結伴出現,卻始終沒有一個共同的名字
模組一最後一站:資料泥團(Data Clumps)。