小A:“模板方法模式與策略模式有什麼不同?”
大B:“模板方法模式與策略模式的作用相常類似。有時(shí)可以用策略模式替代模板方法模式。模板方法模式通過繼承來實(shí)現(xiàn)代碼複用,策略模式使用委託,委託比繼承具有更大的靈活性。繼承經(jīng)常 被錯(cuò)誤的使用。策略模式把不確定的行爲(wèi)集中到一個(gè)接口中,並在主類委託這個(gè)接口?!?
思考剛纔的訂單處理例子,改爲(wèi)策略模式後。
1、把不確定的行爲(wèi)抽取爲(wèi)一個(gè)接口。
代碼:
PublicinterfaceOrderHelper{
publicintgetOrderItemPrice(OrderItemorderItem);
publicintgetSpendingLimit(intcustomerId);
publicintsaveOrder(intcustomerId,inttotal,ListorderItemList);
}
rendercode();
2、而把這個(gè)具體類調(diào)用這個(gè)接口的相應(yīng)方法來實(shí)現(xiàn)具體的邏輯。
代碼:
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類不再是一個(gè)抽象類,而是一個(gè)具體類。Order類委託OrderHelpher接口來完成placeOrder方法所需的基本操作。像在這種情況下使用策略模式更具有優(yōu)勢,策略模式不需要繼承來實(shí)現(xiàn)。而是通過一個(gè)委託對象來實(shí)現(xiàn)。OrderHelper接口無需要去繼續(xù)任何指定的類。而相對來說,採用策略來實(shí)現(xiàn)會(huì)更復(fù)雜一些。由此可見,模板方法模式主要應(yīng)用於框架設(shè)計(jì)中,以確?;惪刂铺幚砹鞒痰倪壿嬳樞颍ㄈ缈蚣艿某跏蓟?。像上面的測試基類中。框架通常需要控制反轉(zhuǎn)。而在一些情況中,優(yōu)級先考慮使用策略模式:當(dāng)需要變化的操作非常多時(shí),採用策略模式把這些操作抽取到一個(gè)接口。當(dāng)那些基本操作的實(shí)現(xiàn)需要與其它類相關(guān)時(shí),應(yīng)該使用策略模式。通過委託接口把行爲(wèi)與實(shí)現(xiàn)完全分離出來(比如數(shù)據(jù)存?。??!”热缬唵翁幚淼膕aveOrder方法,是寫入數(shù)據(jù)庫的。它的實(shí)現(xiàn)與採用何種持久化模式相關(guān)。當(dāng)某些基本操作的實(shí)現(xiàn)可能需要在運(yùn)行時(shí)改變時(shí),可以通過在運(yùn)行時(shí)改變委託對象來實(shí)現(xiàn),而繼承則不能。所以才採用策略模式?!?