一、策略模式和狀態模式的區別和聯繫(本部分轉載自:http://letscoding.cn/java%E4%B8%AD%EF%BC%8C%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E5%92%8C%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8C%BA%E5%88%AB/)html
策略模式經過封裝一組相關算法,爲Client提供運行時的靈活性。Client能夠在運行時,選擇任一算法,而不改變使用算法的Context。一些流行的策略模式的例子是寫那些使用算法的代碼,例如加密算法、壓縮算法、排序算法。另外一方面,狀態模式容許對象,在不一樣的狀態擁有不一樣的行爲。由於現實世界中的對象一般都是有狀態的,因此它們在不一樣狀態,行爲也不同。例如,VM(自動售貨機)只在hasCoin狀態纔給你吐商品;你不投幣,它是不會吐的。如今你能夠清楚的看出它們的不一樣之處了:它們的意圖是不一樣的。狀態模式幫助對象管理狀態,而策略模式容許Client選擇不一樣的行爲。 java
另外一個不那麼容易能看出來的區別是:是誰促使了行爲的改變。策略模式中,是Client提供了不一樣的策略給Context;狀態模式中,狀態轉移由Context或State本身管理。另外,若是你在State中管理狀態轉移,那麼它必須持有Context的引用。例如,在VM的例子中,State對象須要調用VM的setState()方法去改變它的狀態。另外一方面,Strategy從不持有Context的引用,是Client把所選擇的Strategy傳遞給Context。因爲狀態模式和策略模式的區別,是流行的Java設計原則類面試題之一,咱們將會在本文探討在Java中,狀態模式和策略模式的異同,這能夠加深你對它們的理解。面試
類似之處算法
若是你看看狀態模式和策略模式的UML圖,就會發現它們的結構很是類似。使用State對象改變本身行爲的對象被稱爲Context對象;類似的,使用Strategy對象改變本身行爲的對象叫Context對象。記住,Client和Context打交道。在狀態模式中,Context把方法調用委託給當前的狀態對象,而在策略模式中,Context使用的Strategy對象,是被當作參數傳遞過來的,或在Context對象被建立時就被提供的。ide
讓咱們來看看它們之間更多的類似之處:加密
不一樣之處spa
如今咱們知道,狀態模式和策略模式的結構是類似的,但它們的意圖不一樣。讓咱們重溫一下它們的主要不一樣之處:設計
本段譯自:Difference between State and Strategy Design Pattern in Javacode
二、URL圖下載地址(astah/jude):http://pan.baidu.com/s/1hqy0c88orm
三、示例
公共策略規範接口
1 package com.xinye.test.strategy; 2 /** 3 * 策略通用接口 4 * @author xinye 5 * 6 */ 7 public interface IStrategy { 8 public void strategy(); 9 }
默認策略
1 package com.xinye.test.strategy; 2 /** 3 * 默認Strategy 4 * @author xinye 5 * 6 */ 7 public class NormalStrategy implements IStrategy { 8 9 @Override 10 public void strategy() { 11 System.out.println(getClass().getSimpleName() + " strategy()"); 12 } 13 14 }
第一種策略
package com.xinye.test.strategy; /** * 第一種Strategy * @author xinye * */ public class FirstStrategy implements IStrategy { @Override public void strategy() { System.out.println(getClass().getSimpleName() + " strategy()"); } }
第二種策略
1 package com.xinye.test.strategy; 2 /** 3 * 第二種Strategy 4 * @author xinye 5 * 6 */ 7 public class SecondStrategy implements IStrategy { 8 9 @Override 10 public void strategy() { 11 System.out.println(getClass().getSimpleName() + " strategy()"); 12 } 13 14 }
策略Context
1 package com.xinye.test.strategy; 2 /** 3 * 策略模式Context 4 * @author xinye 5 * 6 */ 7 public class Context { 8 9 private IStrategy strategy = new NormalStrategy(); 10 /** 11 * 須要客戶端把策略傳遞過來 12 * @param s 13 */ 14 public void exec(IStrategy s){ 15 strategy = s; 16 strategy.strategy(); 17 } 18 }
客戶端代碼
package com.xinye.test.strategy; /** * 客戶端代碼 * @author xinye * */ public class Client { public static void main(String[] args) { Context context = new Context(); // 傳遞給Context特定的策略 context.exec(new NormalStrategy()); // 傳遞給Context特定的策略 context.exec(new FirstStrategy()); // 傳遞給Context特定的策略 context.exec(new SecondStrategy()); } }
執行結果NormalStrategy strategy()FirstStrategy strategy()SecondStrategy strategy()