小A:“模板方法模式與策略模式有什麼不同?”
大B:“模板方法模式與策略模式的作用相常類似。有時可以用策略模式替代模板方法模式。模板方法模式透過繼承來實現程式碼複用,策略模式使用委託,委託比繼承具有更大的靈活性。繼承經常 被錯誤的使用。策略模式把不確定的行為集中到一個介面中,並在主類委託這個介面。”
思考剛才的訂單處理例子,改為策略模式後。
1、把不確定的行為抽取為一個介面。
程式碼:
PublicinterfaceOrderHelper{
publicintgetOrderItemPrice(OrderItemorderItem);
publicintgetSpendingLimit(intcustomerId);
publicintsaveOrder(intcustomerId,inttotal,ListorderItemList);
}
rendercode();
2、而把這個具體類呼叫這個介面的相應方法來實現具體的邏輯。
程式碼:
publicclassOrder{
privateOrderHelperorderHelpr;
publicvoidsetOrderHelper(OrderHelperorderHelper){
this.orderHelper=orderHelper;
}
publicOrderplaceOrder(intcustomerId,ListorderItemList){
inttotal=0;
for(inti=0;iorderHelpr.getSpendingLimit(customerId)){
thrownewBusinessException(“超出信用額度”+orderHelpr.getSpendingLimit(customerId));
}
intorderId=orderHelpr.saveOrder(customerId,total,orderItemList);
returnnewOrderImpl(orderId,total);
}
}
rendercode();
大B:“這樣Order類不再是一個抽象類,而是一個具體類。Order類委託OrderHelpher介面來完成placeOrder方法所需的基本操作。像在這種情況下使用策略模式更具有優勢,策略模式不需要繼承來實現。而是透過一個委託物件來實現。OrderHelper介面無需要去繼續任何指定的類。而相對來說,採用策略來實現會更復雜一些。由此可見,模板方法模式主要應用於框架設計中,以確保基類控制處理流程的邏輯順序(如框架的初始化)。像上面的測試基類中。框架通常需要控制反轉。而在一些情況中,優級先考慮使用策略模式:當需要變化的操作非常多時,採用策略模式把這些操作抽取到一個介面。當那些基本操作的實現需要與其它類相關時,應該使用策略模式。透過委託介面把行為與實現完全分離出來(比如資料存取)。 比如訂單處理的saveOrder方法,是寫入資料庫的。它的實現與採用何種持久化模式相關。當某些基本操作的實現可能需要在執行時改變時,可以透過在執行時改變委託物件來實現,而繼承則不能。所以才採用策略模式。”