LetsCoding.cn

          天地之間有桿秤,拿秤砣砸老百姓。

          Java中,狀態模式和策略模式的區別

          本文轉自:碼農合作社Java中,狀態模式和策略模式的區別

          Ja
          va開發者,要想恰當的使用狀態模式和策略模式,必須清楚的理解它們之間的區別。雖然狀態模式和策略模式擁有相似的結構,雖然它們都基于SOLID設計原則中的O(開閉原則),但是,它們的意圖是完全不同的。

          策略模式通過封裝一組相關算法,為Client提供運行時的靈活性。Client可以在運行時,選擇任一算法,而不改變使用算法的Context。一些流行的策略模式的例子是寫那些使用算法的代碼,例如加密算法、壓縮算法、排序算法。另一方面,狀態模式允許對象,在不同的狀態擁有不同的行為。因為現實世界中的對象通常都是有狀態的,所以它們在不同狀態,行為也不一樣。例如,VM(自動售貨機)只在hasCoin狀態才給你吐商品;你不投幣,它是不會吐的。現在你可以清楚的看出它們的不同之處了:它們的意圖是不同的。狀態模式幫助對象管理狀態,而策略模式允許Client選擇不同的行為。

          另一個不那么容易能看出來的區別是:是誰促使了行為的改變。策略模式中,是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對象被創建時就被提供的。

          狀態模式UML類圖

          這是專為經典的VM問題而設計的狀態模式UML類圖。你可以看出,VM的狀態是個接口,它有表示不同狀態的具體實現。每一個狀態都持有Context的引用,用它來管理由Context觸發的行為導致的狀態轉移。

          策略模式UML類圖

          這是專為實現排序功能而設計的策略模式UML類圖。因為存在很多排序算法,該模式讓Client在排序時選擇適當的算法。事實上,Java的集合框架就使用這個模式,實現了用來排序的Collections.sort()方法。不同的是,它不允許Client選擇排序算法,而是讓它傳遞Comparator或Comparable接口的實例來指定比較策略。

          讓我們來看看它們之間更多的相似之處:

          1. 添加新的狀態或策略都很容易,而且不需要修改使用它們的Context對象。
          2. 它們都讓你的代碼符合OCP原則。在狀態模式和策略模式中,Context對象對修改是關閉的,添加新的狀態或策略,都不需要修改Context。
          3. 正如狀態模式中的Context會有初始狀態一樣,策略模式同樣有默認策略。
          4. 狀態模式以不同的狀態封裝不同的行為,而策略模式以不同的策略封裝不同的行為。
          5. 它們都依賴子類去實現相關行為。

          不同之處

          現在我們知道,狀態模式和策略模式的結構是相似的,但它們的意圖不同。讓我們重溫一下它們的主要不同之處:

          1. 策略模式封裝了一組相關算法,它允許Client在運行時使用可互換的行為;狀態模式幫助一個類在不同的狀態顯示不同的行為。
          2. 狀態模式封裝了對象的狀態,而策略模式封裝算法或策略。因為狀態是跟對象密切相關的,它不能被重用;而通過從Context中分離出策略或算法,我們可以重用它們。
          3. 在狀態模式中,每個狀態通過持有Context的引用,來實現狀態轉移;但是每個策略都不持有Context的引用,它們只是被Context使用。
          4. 策略實現可以作為參數傳遞給使用它的對象,例如Collections.sort(),它的參數包含一個Comparator策略。另一方面,狀態是Context對象自己的一部分,隨著時間的推移,Context對象從一個狀態轉移到另一個狀態。
          5. 雖然它們都符合OCP原則,策略模式也符合SRP原則(單一職責原則),因為每個策略都封裝自己的算法,且不依賴其他策略。一個策略的改變,并不會導致其他策略的變化。
          6. 另一個理論上的不同:策略模式定義了對象“怎么做”的部分。例如,排序對象怎么對數據排序。狀態模式定義了對象“是什么”和“什么時候做”的部分。例如,對象處于什么狀態,什么時候處在某個特定的狀態。
          7. 狀態模式中很好的定義了狀態轉移的次序;而策略模式并無此需要:Client可以自由的選擇任何策略。
          8. 一些常見的策略模式的例子是封裝算法,例如排序算法,加密算法或者壓縮算法。如果你看到你的代碼需要使用不同類型的相關算法,那么考慮使用策略模式吧。而識別何時使用狀態模式是很簡單的:如果你需要管理狀態和狀態轉移,但不想使用大量嵌套的條件語句,那么就是它了。
          9. 最后但最重要的一個不同之處是,策略的改變由Client完成;而狀態的改變,由Context或狀態自己。

          本文譯自:Difference between State and Strategy Design Pattern in Java

          原創文章,轉載請注明: 轉載自LetsCoding.cn
          本文鏈接地址: Java中,狀態模式和策略模式的區別

          posted on 2014-05-16 03:23 Rolandz 閱讀(6416) 評論(1)  編輯  收藏 所屬分類: 編程實踐

          評論

          # re: Java中,狀態模式和策略模式的區別 2014-06-01 19:12 手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn

          手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn!  回復  更多評論   

          導航

          統計

          留言簿(1)

          隨筆分類(12)

          隨筆檔案(19)

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 囊谦县| 淅川县| 东兰县| 金湖县| 当涂县| 博客| 和田县| 江阴市| 孟州市| 四川省| 筠连县| 喀什市| 牙克石市| 安溪县| 平远县| 荆门市| 汨罗市| 南召县| 周宁县| 胶州市| 霍邱县| 扶余县| 勃利县| 时尚| 巴中市| 连江县| 和平区| 察雅县| 始兴县| 平湖市| 靖边县| 慈溪市| 思茅市| 汾阳市| 仲巴县| 岫岩| 北宁市| 利辛县| 喜德县| 靖远县| 兰溪市|