《研磨设计模式》chap17 策略模式(2) 总结
1. 新增加context 上下文類
eg. 發工資:發人民幣和發美元
public interface PaymentStrategy {//公司給某人真正支付工資 public void pay(PaymentContext ctx); }public class RMBCash implements PaymentStrategy{ public void pay(PaymentContext ctx) { } }public class PaymentContext {//應被支付工資的人員,簡單點,用姓名來代替 private String userName = null;//應被支付的工資的金額 private double money = 0.0;//支付工資的方式策略的接口 private PaymentStrategy strategy = null;public PaymentContext(String userName,double money,PaymentStrategy strategy){this.userName = userName;this.money = money;this.strategy = strategy;}public void payNow(){//使用客戶希望的支付策略來支付工資this.strategy.pay(this);} }public static void main(String[] args) {//創建相應的支付策略PaymentStrategy strategyRMB = new RMBCash();PaymentStrategy strategyDollar = new DollarCash(); //準備小李的支付工資上下文PaymentContext ctx1 = new PaymentContext("小李",5000,strategyRMB);//向小李支付工資ctx1.payNow();1.1 如果要新加一個功能,比如支付到銀行卡,可以新建一個context類
public class Card implements PaymentStrategy{ public void pay(PaymentContext ctx) { PaymentContext2 ctx2 = (PaymentContext2)ctx; //連接銀行,進行轉帳,就不去管了} }public class PaymentContext2 extends PaymentContext {//銀行帳號 private String account = null; public PaymentContext2(String userName,double money,String account,PaymentStrategy strategy){super(userName,money,strategy);this.account = account;}1.2 把context傳給strategy
public class Card2 implements PaymentStrategy{ private String account = ""; public Card2(String account){this.account = account;}public void pay(PaymentContext ctx) { } }public static void main(String[] args) {PaymentStrategy strategyCard = new Card();PaymentContext ctx3 = new PaymentContext2("小王",9000,"010998877656",strategyCard);ctx3.payNow();總結:
-
對于擴展上下文的方式:這樣實現,所有策略的實現風格更統一,策略需要的數據都統一從上下文來獲取,這樣在使用方法上也很統一;另外,在上下文中添加新的數據,別的相應算法也可以用得上,可以視為公共的數據。但缺點也很明顯,如果這些數據只有一個特定的算法來使用,那么這些數據有些浪費;另外每次添加新的算法都去擴展上下文,容易形成復雜的上下文對象層次,也未見得有必要。
-
對于在策略算法的實現上添加自己需要的數據的方式:這樣實現,比較好想,實現起來簡單。但是缺點也很明顯,跟其他策略實現的風格不一致,其他策略都是從上下文中來獲取數據,而這個策略的實現一部分數據來自上下文,一部分數據來自自己,有些不統一;另外,這樣一來,外部使用這些策略算法的時候也不一樣了,難于以一個統一的方式來動態切換策略算法。
2. 容錯恢復
log要么記錄到txt文件,或者記錄到數據庫。
public interface LogStrategy { public void log(String msg); }public class FileLog implements LogStrategy{public void log(String msg) { } }public class LogContext {//記錄日志 public void log(String msg){ LogStrategy strategy = new DbLog();try{strategy.log(msg);}catch(Exception err){//出錯了,那就記錄到文件中strategy = new FileLog();strategy.log(msg);}} }public static void main(String[] args) {LogContext log = new LogContext();log.log("記錄日志");log.log("再次記錄日志");}3. 策略模式加模板模式
好幾個策略有共同的部分。
public abstract class LogStrategyTemplate implements LogStrategy{ public final void log(String msg) {//第一步:給消息添加記錄日志的時間DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");msg = df.format(new java.util.Date())+" 內容是:"+ msg;//第二步:真正執行日志記錄doLog(msg);}//真正執行日志記錄,讓子類去具體實現 protected abstract void doLog(String msg); }4. 總結
本質還是“分離算法,選擇實現”,因為分離并封裝了算法,才能夠很容易地修改和添加算法;也能很容易地動態切換使用不同的算法,也就是動態選擇一個算法來實現需要的功能。
4. 1 上下文
如果沒有上下文,那么就需要客戶端來直接與具體的策略交互,尤其是當需要提供一些公共功能,或者是相關狀態存儲的時候,會大大增加客戶端使用的難度。因此,引入上下文還是很必要的,有了上下文,這些工作就由上下文來完成了,客戶端只需要與上下文交互就可以了,這樣會讓整個設計模式更獨立、更有整體性,也讓客戶端更簡單。
總結
以上是生活随笔為你收集整理的《研磨设计模式》chap17 策略模式(2) 总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《研磨设计模式》chap17 策略模式(
- 下一篇: 《研磨设计模式》chap15 组合模式