狀態模式
![]() |
狀態模式是一种行為類型的软件设计模式,它可以讓物件在其内部狀態有變化時,改為其行為。这种模式有點像有限状态机的概念。狀態模式可以被當成成一種策略模式,它能够在調用模式介面中所定義的方法来切換策略。
计算机编程中,狀態模式用於,當同一物件基於其內部狀態而有不同行為,將其行為進行封裝。對於物件来说,这可以是一种更為簡潔方式,可以在运行时更改其行为而无需诉诸条件语句,从而提高可维护性。 [1] :395
概述
[编辑]![](http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/W3sDesign_State_Design_Pattern_UML.jpg/220px-W3sDesign_State_Design_Pattern_UML.jpg)
狀態設計模式是《設計模式:可復用物件導向軟體的基礎》所收錄的二十三個之一,本書描述了如何解决常見的设计问题。此类问题涵盖了灵活且可重用的面向对象软件的设计,例如易于实现、更改、测试和重用的对象。 [3]
狀態模式常用來解決两個主要問題: [4]
- 当对象的内部状态改变时,它的行为也应该改变。
- 应独立定义特定于国家的行为。也就是说,添加新状态不应影响现有状态的行为。
在類別中直接為特定狀態實作行為是不夠彈性的,因為它將類別與特定行為綁定,這將使得如果要增加新的狀態或改變狀態的行為,而且這些行為是與類別獨立的,仍無法在不更改類別的情况下達到。因此,此模式描述了兩種解決方案:
- 定義單獨的(狀態)物件,封装每個裝態的特定的行为。即,定義一個介面(狀態)以用於執行與狀態有關的特定行為,並為每種狀態實現該接口的類別。
- 類別不要直接實現與狀態有關的特定行為,而是將其委由當前戕態物件。
這使得類別與業於狀態的行為的實作可以獨立開來。新的狀態可以通過定義新的狀態類別来實現。類別可以在運行時,藉由改變當前狀態物件来改變其行為。
结构
[编辑]![](http://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/State_Design_Pattern_UML_Class_Diagram.svg/400px-State_Design_Pattern_UML_Class_Diagram.svg.png)
在随附的统一建模语言(UML)類別圖中, Context
類別不直接实现特定于状态的行为。相反, Context
用 State
介面以执行特定于状态的行为 ( state.handle()
),这使得 Context
獨立於特定于狀態行為的实现方式。 ConcreteStateA
和 ConcreteStateB
類別实现 State
介面,即实现(封装)每个状态的特定行为。 UML序列图 說明了运行时互動:
Context
对象将特定于状态的行为委托给不同的State
对象。首先, Context
调用handle(this)
時,會是基於其当前(初始)狀態 ( ConcreteStateA
) 的行為,其會執行操作並調用 Context.
setState(ConcreteStateB)
來將當前狀態更改为ConcreteStateB
。下一次, Context
再次调用 handle(this)
會是基於其當前状态对象 ( ConcreteStateB
) ,其會執行操作,並将當前狀態更改为 ConcreteStateA
。
参考
[编辑]- ^ 1.0 1.1 Erich Gamma; Richard Helm; Ralph Johnson; John M. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. 1995. ISBN 0-201-63361-2. 引用错误:带有name属性“GOF”的
<ref>
标签用不同内容定义了多次 - ^ The State design pattern – Structure and Collaboration. w3sDesign.com. [2017-08-12].
- ^ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software
. Addison Wesley. 1994: 305ff. ISBN 0-201-63361-2.
- ^ The State design pattern - Problem, Solution, and Applicability. w3sDesign.com. [2017-08-12]. (原始内容存档于2023-11-17).