`

[原创] State Pattern 状态模式的介绍与应用

阅读更多

Part I 什么是状态模式

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类 -- 《Head First – Designer Pattern》译本

 

Part II 状态模式与策略模式的关系

 策略模式强调的是对算法的抽象与封装,而状态模式则侧重于当对象内部状态改变时所引起的对象行为的改变!

虽然两种模式的形式和使用上相类似,但是他们所处理的问题是不一样的。

 

Part III 解决吃饭-工作问题

首先让我们模拟一个场景:

1. 有一个Person的对象;

2. 这个人有两个行为:吃饭 -- 工作;

3. 这个人有三种不同的状态:吃饱 -- 正常 -- 饥饿;

4. 这三种状态的切换如下:

1)吃饱--[工作]--正常;

2)正常--[工作]--饥饿;

3)饥饿--[吃饭]--正常;

4)正常--[吃饭]--吃饱;

相信读者看到这里一定会想:这样太简短不过了,我们给它一个变量来记录他的状态,然后根据变量的值来判断他的行为就可以了!

好,我们就依照这个思路下如下的代码:

package nopattern;
public class Person {
	
	private String state = "normal";
	
	public void eat() {
		if (state.equals("hungry"))
			System.out.println("终于有吃的了...");
		else if (state.equals("normal"))
			System.out.println("吃完就变得很饱...");
		else if (state.equals("full"))
			System.out.println("我不能再吃了...");
		else 
			System.out.println("非人状态不予考虑");
	}
	
	public void work() {
		if (state.equals("hungry"))
			System.out.println("不给我吃我肯定不干...");
		else if (state.equals("normal"))
			System.out.println("再干下去会变得很饿...");
		else if (state.equals("full"))
			System.out.println("我可以干更多的活...");
		else 
			System.out.println("非人状态不予考虑");
	}
	
}

然后我们尝试去测试这个类:

package nopattern;
import pattern.state.entity.Person;
public class Test {
	public static void main(String[] args) {
		Person me = new Person();
		me.eat(); // 吃完就变得很饱...
		me.eat(); // 我不能再吃了...
		me.eat(); // 我不能再吃了...
		me.work(); // 我可以干更多的活...
		me.work(); // 再干下去会变得很饿...
		me.work(); // 不给我吃我肯定不干...
		me.eat(); // 终于有吃的了...
		me.eat(); // 吃完就变得很饱...
		me.eat(); // 我不能再吃了...
	}
}

这样看来,我们写的代码真的很完美了,实现了对象状态的改变引起行为上的改变。但是请细心的想一下,在面向对象程序设计中,我们会接触到这样一个名词:单一责任原则,我们所编写的代码,把对象状态的维护交给了Person这个类来负责,这样做合适吗?

退一步来说,当我们的Person有更多的状态时(例如:“饿得快要晕过去了,连吃饭的力气都没有”和“吃饱了撑着,想干活都干不了了”),那我们是不是也要去修改Person类所有与状态有关的行为呢?我们是否真的需要那么多的if-else呢?

现在,面对上面如此糟糕的代码,有砸电脑的冲动吗?

 

Part IV 用设计模式来解决吃饭-工作问题

相信到这里,读者们肯定会抱怨说:你X的别再给我卖关子了!!!别急,我们先来分析一下状态这个有意思的东西。

首先我们要清楚一件事情,这个人的状态能不能给抽象出来呢?例如在某些状态中,这些状态中会有共性?

那让我们尝试去分离出Hungry、Full和Normal三种状态的共性吧!

package pattern.state.state;
public interface State {
	void eat();
	void work();
}

有了这个状态的高度抽象,我们还等什么?马上实现我们的三种状态吧!

package pattern.state.state;
import pattern.state.entity.Person;
public class FullState implements State {
	
	private Person me;
	
	public FullState(Person me) {
		this.me = me;
	}
	@Override
	public void eat() {
		System.out.println("我不能再吃了...");
	}
	@Override
	public void work() {
		System.out.println("我可以干更多的活...");
		me.setState(me.NORMAL_STATE);
	}
}
package pattern.state.state;
import pattern.state.entity.Person;
public class HungryState implements State {
	private Person me;
	public HungryState(Person me) {
		this.me = me;
	}
	@Override
	public void eat() {
		System.out.println("终于有吃的了...");
		me.setState(me.NORMAL_STATE);
	}
	@Override
	public void work() {
		System.out.println("不给我吃我肯定不干...");
	}
}
package pattern.state.state;
import pattern.state.entity.Person;
public class NormalState implements State {
	
	private Person me;
	public NormalState(Person me) {
		this.me = me;
	}
	@Override
	public void eat() {
		System.out.println("吃完就变得很饱...");
		me.setState(me.FULL_STATE);
	}
	@Override
	public void work() {
		System.out.println("再干下去会变得很饿...");
		me.setState(me.HUNGRY_STATE);
	}
}

上面定义了三种状态,其中有些方法我们还没有提及到的,请继续往下阅读。

package pattern.state.entity;
import pattern.state.state.FullState;
import pattern.state.state.HungryState;
import pattern.state.state.NormalState;
import pattern.state.state.State;
public class Person {
	public final State FULL_STATE = new FullState(this);
	public final State NORMAL_STATE = new NormalState(this);
	public final State HUNGRY_STATE = new HungryState(this);
	private State state = NORMAL_STATE;
	
	public void eat() {
		state.eat();
	}
	public void work() {
		state.work();
	}
	public State getState() {
		return state;
	}
	public void setState(State state) {
		this.state = state;
	}
}

不错,就是这么的简单。我们现在已经把状态变化的控制从Person类中分离出来了,由我们的State实现类来控制,我们的Person类只关心自己的状态和吃饭工作问题,状态的问题就由状态自己来解决吧!当我们有更多的状态时,我们只需要修改相应变换的状态部分就可以实现状态间的切换,世界变得那么的美好!

分享到:
评论

相关推荐

    状态模式 State Pattern

    ### 状态模式(State Pattern) #### 概念与定义 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,使对象看起来像是修改了它的类。该模式通过引入一个代表各种状态的类以及一个行为随着这些...

    设计模式之状态模式(State Pattern)

    在实际应用中,状态模式可以降低系统的复杂度,提高代码的可读性和可维护性。它将与特定状态相关的行为封装到具体的State类中,使得状态的变化不会影响到Context的其他部分。同时,通过引入新的具体状态类,可以轻松...

    JackChan1999#Java-Degisn-Patterns#状态模式-State Pattern1

    状态模式-State Pattern状态模式-State Pattern【学习难度:,使用频率:】状态模式-State Pattern处理对象的多种状态及其相互

    《设计模式》实战---状态模式(State Pattern)

    在《设计模式》实战---状态模式(State Pattern)这篇文章中,作者可能详细探讨了以下关键点: 1. **模式定义**:状态模式允许对象在内部状态改变时改变其行为,对象看起来好像修改了它的类。这通过将每个状态封装...

    状态模式(State Pattern)是一种行为设计模式

    状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式将一个对象的行为分解为各个独立的状态,并且每个状态都封装在自己的类中,使得对象在...

    基于state pattern实现的xml解释器

    在软件设计领域,状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。在这个案例中,“基于state pattern实现的xml解释器”指的是一个XML解析器,该...

    Head First 设计模式 (十) 状态模式(State pattern) C++实现

    通过这种方式,状态模式将与特定状态相关的复杂逻辑封装在独立的类中,使得代码更易于理解和维护。此外,它还允许在运行时添加新的状态,增强了系统的灵活性。在Head First的书籍中,这种模式通常通过生动的示例和...

    详解Stateflow建模与应用实例,简单stateflow建模实例,matlab

    为了更好地理解和应用Stateflow,我们可以参考提供的"Stateflow逻辑系统建模.pdf"和"详解Stateflow建模与应用实例.pdf"文档。这些材料应该包含了一系列简单的Stateflow建模实例,可能包括简单的开关控制逻辑、自动化...

    设计模式C++学习之状态模式(State)

    状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。...通过理解并正确应用状态模式,开发者能够更优雅地处理对象状态的动态变化,提高代码的可读性和可维护性。

    nevstop#LabVIEW-Design-Pattern#状态模式(State Pattern)1

    状态模式定义Allow an object to alter its behavior when its internal state changes. The

    设计模式之状态模式(State)

    状态模式是一种行为设计模式,它使对象能够在内部状态改变时改变其行为,看起来好像改变了它...例如,游戏中的角色状态(如待机、攻击、防御等)、用户的登录/注销状态、订单的不同处理阶段等场景都可以应用状态模式。

    Android的状态机模式StateMachine与State

    在博文《Android的状态机模式StateMachine与State》中,作者可能会详细介绍如何创建和使用这两种组件。通常,状态机的实现会涉及到以下步骤: 1. **定义状态接口或抽象类**:创建一个State接口或抽象类,其中包含...

    StateMachine 状态机机制深入解析

    StateMachine 状态机机制深入解析 StateMachine 状态机机制是指在软件开发中,使用状态机来描述和处理...在 Spring 框架中,StateMachine 状态机机制可以通过 Spring StateMachine 实现,并且可以应用于各种业务场景。

    设计模式之状态模式State

    状态模式通常包含三个主要角色:Context(上下文)、State(抽象状态)和ConcreteState(具体状态)。 上下文是拥有状态的对象,它定义了与该状态相关的接口,并负责在适当的时候将请求委托给相应的状态对象处理。...

    设计模式的状态模式的例子

    在"StatePattern"这个压缩包中,我们可能找到以下文件: - `State.java`: 定义了状态接口。 - `NormalState.java`, `BusyState.java`: 具体的状态类,实现了`State`接口并提供了对应状态的行为。 - `Context.java`:...

    管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程.doc

    "状态机在订单状态管理中的应用及 COLA StateMachine 的介绍" 在订单状态管理中,状态机模式是一种常用的解决方案,但是在实际项目中,状态机的使用率并没有想象中那么高。笔者在电商领域进行后端开发时,发现了...

    C++设计模式课件18_State_状态模式.pdf

    本文将详细介绍状态模式的概念、实现原理以及在C++中的具体应用。 #### 二、状态模式定义 状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种方式使得对象看起来像是改变了它的类...

    C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式

    标题和描述均提到了"C#面向对象设计模式"中的State状态模式,这表明文章的核心内容是围绕State模式在C#编程语言中的应用展开。State模式是一种行为设计模式,旨在允许对象在其内部状态改变时,其行为也能相应地改变...

    State Machine Java Pattern

    本文介绍了一种新的面向对象设计模式——状态机设计模式(State Machine Design Pattern)。该模式扩展了状态设计模式的功能,使对象能够根据其内部状态的变化来改变自身的行为。通过引入事件驱动的方法,状态机模式...

Global site tag (gtag.js) - Google Analytics