允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
考虑一个表示网络连接的类TCPConnection。一个TCPConnection对象的状态处于若干不同状态之一:连接已建立(Established)、正在监听(Listening)、连接已关闭(Closed)。当一个TCPConnection对象收到其他对象的请求时,它根据自身的当前状态做出不同的反应。例如,一个Open请求的结果依赖于该连接是处于连接已关闭状态还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。
这一模式的关键思想是引入了一个称为TCPState的抽象类来表示网络的连接状态。TCPState类为各表示不同的操作状态的子类声明了一个公共接口。TCPState的子类实现与特定状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立状态和连接已关闭状态的行为。
TCPConnection类维护一个表示TCP连接当前状态的状态对象(一个TCPState子类的实例)。TCPConnection类将所有与状态相关的请求委托给这个状态对象。TCPConnection使用它的TCPState子类实例来执行特定于连接状态的操作。
一旦连接状态改变,TCPConnection对象就会改变它所使用的状态对象。例如,当连接从已建立状态转为已关闭状态时,TCPConnection会用一个TCPClosed的实例来代替原来的TCPEstablished的实例。
一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖与其他对象而独立变化。
1、Context将与状态相关的请求委托给当前的ConcreteState对象处理。
2、Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
3、Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不再需要直接与状态对象打交道。
4、Context或ConcreteState子类都可决定哪个状态是另外哪一个状态的后续者,以及是在何种条件下进行状态转换。
State模式有下面效果:
1、它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。State模式将所有与一个特定的状态相关的行为都放入一个对象中。因为所有与状态相关的代码都存在于某一个State子类中,所以通过定义新的子类可以很容易的增加新的状态和转换。
另一个方法是使用数据值定义内部状态并且让Context操作来显式地检查这些数据。但这样将会使整个Context的实现中遍布看起来很相似的条件语句或case语句。增加一个新的状态可能需要改变若干个操作,这就使得维护变得复杂了。
State模式避免了这个问题,但可能会引入另一个问题,因为该模式将不同状态的行为分布在多个State子类中。这就增加了子类的数目,相对于单个类的实现来说不够紧凑。但是如果哟许多状态时这样的分布实际上更好一些,否则需要使用巨大的条件语句。
State模式提供了一个更好的方法来组织与特定状态相关的代码。决定状态转移的逻辑不在单块的if或switch语句中,而是分布在State子类之间。将每一个状态转换和动作封装到一个类中,就把着眼点从执行状态提高到整个对象的状态。这将使代码结构化并使其意图更加清晰。
2、当一个对象仅以内部数据值来定义当前状态时,其状态仅表现为对一些变量的赋值,这不够明确。为不同的状态引入独立的对象使得转换变得更加明确。而且,State对象可保证Context不会发生内部内部状态不一致的情况,因为从Context的角度看,状态转换是原子的。只需重新绑定一个变量,即Context的State对象变量,而无需为多个变量赋值。
3、State对象可被共享。如果State对象没有实例变量,即它们表示的状态完全以它们的类型来编码,那么各Context对象可以共享一个State对象。当状态以这种方法被共享时,它们必然是没有内部状态,只有行为的轻量级对象(Flyweight
)。
State模式不指定哪一个参与者定义状态转换准则。如果该准则是固定的,那么它们可在Context中完全实现。然而若让State子类自身指定它们的后续状态以及何时进行转换,通常更灵活更合适。这需要Context增加一个接口,让State对象显式地设定Context的当前状态。
用这种方法分散转换逻辑可以很容易地定义新的State子类来修改和扩展该逻辑。这样做的一个缺点是,一个State子类至少拥有一个其他子类的信息,这就再各子类之间产生了实现依赖。
Flyweight模式解释了何时以及怎样共享状态对象。
状态对象通常是Singleton。
分享到:
相关推荐
状态模式通过将状态对象引入到系统中,将对象的行为委托给当前状态对象来执行,从而解耦了对象本身与具体状态之间的关系。 在C#中实现状态模式,通常需要以下几个步骤: 1. 定义上下文(Context):这是使用状态...
c++设计模式-行为型模式-状态模式;qt工程;c++简单源码; 状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
1. **环境类(Context)**:持有一个对状态对象的引用,通常包含一个行为,该行为可以根据状态对象的不同而变化。 2. **抽象状态类(State)**:定义所有可能的状态以及在这些状态之间的转换操作。这是一个接口或...
8. **工具应用**:在实际开发中,状态模式常常与其他设计模式结合使用,如工厂模式用于创建状态对象,策略模式用于更灵活的状态行为选择。此外,一些现代编程语言提供了枚举类或类似功能,可以简化状态模式的实现。 ...
状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。在这个示例中,我们关注的是如何使用Java实现一个审批流程,特别是涉及二级审批的场景。这个压缩包文件包含了一个...
- 封装了转换规则:状态模式将与特定状态相关的行为封装在各自的状态对象中,使得转换规则被隐藏,降低了系统的复杂性。 - 对象行为的扩展更加灵活:只需添加新的具体状态类和状态转换逻辑,而无需修改现有代码。 - ...
状态模式通过将对象的状态抽象出来,并将状态转换的逻辑封装在状态对象中,从而实现了状态与行为的解耦。这种模式不仅简化了代码,还提高了系统的可扩展性和可维护性。然而,过度使用状态模式可能会导致类爆炸,因此...
状态模式将状态封装成独立的类,并将请求委托给当前状态对象,从而实现状态的切换和状态行为的变化。 状态模式的优点: * 可以将状态和行为分离,使得对象的行为可以随着状态的改变而改变,从而实现更加灵活的设计...
状态模式是一种行为设计模式,它使你能在运行时改变对象的行为。在状态模式中,一个对象的状态变化会导致其行为的变化,这种变化不是通过改变对象的类来实现的,而是通过改变对象的状态。这个模式的核心是封装可能...
总之,状态模式提供了一种在运行时改变对象行为的方法,通过将行为封装在独立的状态对象中,使得代码更加模块化,易于理解和维护。在需要根据对象状态动态改变其行为的场景下,状态模式是一个非常实用的设计模式。
该模式通过引入一个代表各种状态的类以及一个行为随着这些状态对象的变化而变化的上下文(context)类来实现。 #### 基本原理 在状态模式中,我们定义了一系列的状态类,每个状态类都有一个或多个方法来描述当前状态...
- 状态模式(State):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎改变了它的类。 - 策略模式(Strategy):定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法的变化独立...
如果在`handleOperation()`中某些条件满足,状态对象可能会调用`changeState()`来改变`Machine`的状态。 状态模式的优点包括: - 它封装了状态转换逻辑,使得状态转换更易于理解和管理。 - 它使得增加新的状态和...
总的来说,状态模式在处理对象行为与状态紧密相关的场景时非常有效。通过将行为委托给状态对象,可以更灵活地管理对象的行为,同时避免了复杂的条件判断逻辑。在Java编程中,合理地使用状态模式能够显著提升代码的...
此外,还有一个上下文类(Context),它持有一个状态对象的引用,并通过这个引用调用状态对象的方法来执行相应的行为。 以下是一个简化的C++状态模式实现步骤: 1. **定义抽象状态类**: ```cpp class State { ...
核心是有一个上下文(Context)角色,它持有一个当前状态对象的引用,并通过这个引用调用相应的行为。当上下文的状态发生变化时,会切换到对应的状态对象,从而执行不同的操作。 下面是一个简单的状态模式实现示例: ...
从抽象的角度来看,可以将层次状态机视为一种元模式,因为它可以衍生出各种结构化的用途,成为自身的设计模式(行为模式)。这类似于面向对象设计模式,它们建立在继承和多态的元模式之上。 ### 状态导向编程的关键...
测试程序可能通过改变上下文对象中存储的状态对象来模拟状态的切换,从而展示不同的行为。 状态模式的优点包括: 1. 封装了转换规则:状态对象封装了状态转换的逻辑,使得状态转换更加清晰。 2. 使状态转换代码...
Stampit 是一个轻量级的 JavaScript 工具,它允许创建可组合的对象,通过“stamp”(一种行为模式)来增强对象的功能。 ### Stampit 简介 Stampit 是一种面向行为的编程工具,它将类的概念转化为更简单、更模块化...