JavaRush /Java Blog /Random-TW /Java 中狀態模式與策略模式的區別
0xFF
等級 9
Донецк

Java 中狀態模式與策略模式的區別

在 Random-TW 群組發布
為了在核心 Java 應用程式中正確使用狀態策略模式,Java 程式設計師清楚地理解它們之間的差異非常重要。儘管狀態和策略這兩種模式具有相似的結構,並且都基於開放/封閉原則,代表SOLID 原則中的“O”,但它們的意圖完全不同。 Java中的策略Java 中狀態模式和策略模式的差異 - 1模式用於封裝相關的演算法集,為客戶端提供執行彈性。客戶端可以在運行時選擇任何演算法,而無需更改使用. 策略模式的一些流行範例是編寫使用演算法的程式碼,例如加密、壓縮或排序。另一方面,狀態模式允許物件在不同狀態下表現不同。因為在現實世界中一個物件往往是有狀態的,並且在不同的狀態下它的表現是不同的,例如自動販賣機只有處於 狀態 的時候才賣商品,除非你往裡面投了一枚硬幣,它才賣東西。現在你可以清楚地看到策略模式和狀態模式之間的區別,這些是不同的意圖。狀態模式幫助物件管理狀態,而策略模式允許客戶端選擇不同的行為。另一個不太容易看出的差異是誰在推動行為的改變。在策略模式中,這是一個向上下文提供各種策略的客戶端;在狀態模式中,轉換由上下文或物件本身的狀態控制。此外,如果您自己管理 State 物件中的狀態更改,則必須有對上下文的引用,例如,自動販賣機必須能夠呼叫方法來更改上下文的當前狀態。另一方面,策略物件從不包含對上下文的參考;客戶端本身將其選擇的策略傳遞給上下文。狀態模式和策略模式之間的差異是有關 Java 模式的常見面試問題之一,在這篇關於 Java 模式的文章中我們將仔細研究它。我們將探討 Java 中的策略模式和狀態模式之間的一些異同,這將有助於您加深對這些模式的理解。 StrategyhasCoinsetState()

狀態模式和策略模式之間的相似之處

如果您查看狀態模式和策略模式的 UML 圖,您會發現兩者看起來相似。使用 State 來更改其行為的物件稱為Context-object,類似地,使用 Strategy 來更改其行為的物件稱為Context-object。請記住,客戶端與Context物件進行互動。在 State 模式的情況下,上下文將呼叫方法委託給 State 對象,該物件作為當前物件保存;在 Strategy 模式的情況下,上下文使用 Strategy 物件作為參數或在建立期間提供物件的上下文。 Java 中狀態模式的 UML 圖 Java 中狀態模式和策略模式的差異 - 2這個狀態模式的 UML 圖描述了用 Java 建立物件導向自動販賣機設計的經典問題。您可以看到自動販賣機的狀態是使用介面來表示的,然後該介面有一個實作來表示特定的狀態。每個狀態也引用物件上下文,以作為上下文中呼叫的操作的結果轉換到另一個狀態。 Java 中策略模式的 UML 圖 Java 中狀態模式和策略模式的差異 - 3該策略模式的 UML 圖包含各種功能實作。由於排序演算法有很多種,這種設計模式允許客戶端在對物件進行排序時選擇一種演算法。事實上,Java Collection 框架使用這種模式來實作一種Collections.sort()用於對 Java 中的物件進行排序的方法。唯一的區別是,它不允許客戶端選擇排序演算法,而是允許客戶端透過將 Comparator或 Comparable 介面的實例傳遞給 Java 來指定比較策略。讓我們來看看 Java 中這兩種主要設計模式之間的一些相似之處:
  1. 狀態和策略這兩種模式都可以輕鬆新增狀態和策略,而不會影響使用它們的物件的上下文。

  2. 這兩者都根據開放/封閉原則維護您的程式碼,這意味著設計將對擴展開放,但對修改封閉。在狀態和策略模式的情況下,物件的上下文禁止修改、引入新的狀態或新的策略,或不需要修改其他狀態的上下文,或進行最小的變更。

  3. 就像狀態模式中物件上下文以物件的初始化狀態開始一樣,在 Java 中的策略模式中,物件上下文也有一個預設策略。

  4. 狀態模式以不同的物件狀態的形式表示不同的行為,而策略模式以不同的物件策略的形式表示不同的行為。

  5. 策略和狀態這兩種模式都依賴行為實現的子類別。每個具體策略都擴展一個抽象策略;每個狀態都是用來表示狀態的介面或抽象類別的子類別。

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

現在我們知道狀態和策略模式在結構上是相似的,但它們的意圖是不同的。讓我們看看這些設計模式之間的一些關鍵差異。
  1. 策略模式封裝了一組相關的演算法,並允許客戶端在運行時使用可互換的行為,而不管運行時的組合和委託,而狀態模式則幫助類別在不同的狀態下表現出不同的行為。

  2. 狀態和策略模式之間的下一個差異是狀態封裝了物件的狀態,而策略模式封裝了演算法或策略。由於狀態與物件相關聯,因此無法重複使用,但透過將策略或演算法與其上下文解耦,我們可以重複使用它。

  3. 在狀態模式中,個人狀態可能包含對上下文的引用以實現狀態之間的轉換,但策略不包含對其使用的上下文的引用。

  4. 策略的實作可以作為參數傳遞給將使用它的對象,例如 Collection.sort() 接受一個比較器,它是一個策略。另一方面,狀態是物件上下文本身的一部分,隨著時間的推移,物件的上下文從一種狀態轉換到另一種狀態。

  5. 雖然策略和狀態都遵循開放/封閉原則,但策略也遵循單一責任原則,因為每個策略都包含單獨的演算法,不同的策略是相互獨立的。改變一種策略並不需要改變另一種策略。

  6. 策略模式和狀態模式之間的另一個理論上的區別是,創建者定義了物件的「如何」部分,例如「如何」排序物件對資料進行排序,而狀態模式定義了「什麼」和「何時」部分物件的屬性,例如當物件處於某種狀態時可以做什麼。

  7. 狀態轉換的順序在狀態模式中被明確定義;而策略模式則沒有這樣的要求。客戶可以自由選擇他選擇的策略的任何實施。

  8. 策略模式的一些常見範例是演算法的封裝,例如排序演算法、加密演算法或壓縮演算法。如果您發現您的程式碼必須使用不同種類的相關演算法,您應該考慮使用策略模式。另一方面,認識狀態模式的使用非常容易,如果您需要控制狀態以及狀態之間的轉換而不需要大量巢狀條件語句,那麼狀態模式是正確的使用模式。

  9. 狀態和策略模式之間最後但最重要的區別之一是,對策略的變更由客戶端執行,而對狀態的變更可以由上下文或物件的狀態本身執行。

這就是Java 中狀態模式和策略模式的差異。正如我所說,兩者在類別和 UML 圖中看起來很相似,都提供開放/封閉原則並封裝行為。使用策略模式來封裝在執行時間暴露給上下文的演算法或策略(可能作為參數或複合物件),並使用狀態模式來控制 Java 中的狀態轉換。原文在這裡
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION