在服務導向架構的服務實作當中,每一個服務處理的主要流程大致上會依照下列步驟來實作:
- 拆解訊息
- 驗證欄位
- 資料處理及運算
- 回應處理結果
然而,在大部分驗證欄位及少部分資料處理及運算的情況下,我們常會碰到需要流程控制分歧狀況,使得程式碼的實作變得很繁複而不容易抽離以達到重複使用的模組。舉個例子來說,付款的交易需要檢核付款者帳號、帳戶餘額、收款銀行與帳號等資訊,程式碼大概會長得像這樣:
public PaymentResult pay(PaymentRequest request) {
PaymentResult response = PaymentResult.getNoting();
if (isPayerValidated(request)) {
if (isPayerBalanceEnough(request)) {
if (isPayeeValidated(request)) {
response = debitPayer(request);
sendFinpay(request);
}
else {
response = getBansta(request, PAYEE_IS_NOT_AUTHORITY);
}
}
else {
response = getBansta(request, BALANCE_IS_NOT_ENOUGH);
}
}
else {
response = getBansta(request, PAYER_IS_NOT_AUTHORITY);
}
return response;
}
當然,上面這一段程式碼還可以從巢狀 if 的寫法改成板狀 if,再加上防衛子句,程式碼會變得比較清晰可讀,但無可避免的,在程式碼當中還是免不了要處理非主流程的分支處理。這樣的缺點是增加每一個服務的實作,這些非主要流程的分支處理都無法省略,無形之中將會分散編程者聚焦程度與增加人為錯誤的疏失。
其實,要解決這個問題並不困難,但需要設計思維的轉變,只需要把命令式編程改成宣告式編程就可以了,這樣我們就可以運用延遲運算的手法來減少分支處理的出現次數。 閱讀全文 →