小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方法,是寫入數據庫的。它的實現與採用何種持久化模式相關。當某些基本操作的實現可能需要在運行時改變時,可以通過在運行時改變委託對象來實現,而繼承則不能。所以才採用策略模式。”