`
wangwengcn
  • 浏览: 172768 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

20.状态模式(State Pattern)

阅读更多

1.定义

当一个对象内在状态改变时,允许其改变行为,这个对象看起来像改变了其类。
状态模式的核心是封装。

 

2.要解决的问题-过多的if-else状态判断

对象如何在每一种状态下表现出不同的行为?
在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接解决方案是将这些所有可能发生的情况全都考虑到。然后使用if... ellse语句来做状态判断来进行不同情况的处理。但是对复杂状态的判断就显得“力不从心了”。随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱。维护也会很麻烦。那么我就考虑只修改自身状态的模式。

例子1:按钮来控制一个电梯的状态,一个电梯开们,关门,停,运行。每一种状态改变,都有可能要根据其他状态来更新处理。例如,开门状体,你不能在电梯处于运行状态的时候开门,而是在电梯处于静止状态下才能开门。

例子2:我们给一部手机打电话,就可能出现这几种情况:用户开机,用户关机,用户欠费停机,用户消户等。 所以当我们拨打这个号码的时候:系统就要判断,该用户是否在开机且不忙状态,又或者是关机,欠费等状态。但不管是那种状态我们都应给出对应的处理操作。

 

3.要点

  • 策略模式和状态模式是双胞胎,它们有相同的类图,但是它们的意图不同。策略模式是围绕可以互换的算法来成功创建业务的,然而状态模式是通过改变对象内部的状态来帮助对象控制自己的行为.
  • Context将与状态相关的操作委托给当前的Concrete State对象处理。
  • Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
  • Context或Concrete State类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。也就是说可以在State中保存对Concrete State的引用,在必要时设置具体的状态,做到状态的转换。
  • 一般来讲,当状态转换是固定的时候,状态转换就适合放在Context中。然而,当转换是更动态的时候,通常会放到具体的状态类中进行。(具体状态类持有Context的引用,实现状态的转换) 。

状态模式类图:

 

4.状态模式的使用场景

  • 行为随状态改变而改变的场景:这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式。
  • 条件、分支判断语句的替代者:在程序中大量使用switch或者if-else判断语句会导致程序结构不清晰,逻辑混乱,使用状态模式能很好的避免这一问题,它通过扩展子类实现了条件的判断处理。

下面请看状态模式的通用代码:

 

package _20StatePattern;

/**
 * 抽象状态角色
 */
public abstract class State {
	
	// 定义一个环境角色,供子类访问
	protected Context context;

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}
	
	// 行为1
	public abstract void openDoor();
	// 行为2
	public abstract void closeDoor();
}
 
package _20StatePattern;

/**
 * 开门状态
 */
public class OpenDoorState extends State {

	@Override
	public void openDoor() 
	{
		// 当前状态已经是开门了,再执行开门动作就不需要做任何事情
	}

	@Override
	public void closeDoor() {
		// 将状态设置为关门状态
		super.context.setCurrentState(Context.CloseState);
		// 执行关门动作
		super.getContext().closeDoor();
		System.out.println("状态:开门->关门");
	}

}
 
package _20StatePattern;

/**
 * 关门状态
 */
public class CloseDoorState extends State {

	@Override
	public void openDoor() 
	{
		// 将状态设置为开门状态
		super.context.setCurrentState(Context.OpenState);
		// 执行开门动作
		super.getContext().openDoor();
		System.out.println("状态:关门->开门");
	}

	@Override
	public void closeDoor() 
	{
		// 当前状态已经是关门了,再执行关门动作就不需要做任何事情
	}

}
 
package _20StatePattern;

/**
 * 具体环境角色
 */
public class Context{

	// 定义状态
	public final static State OpenState = new OpenDoorState();
	public final static State CloseState = new CloseDoorState();
	
	// 设置当前状态
	private State currentState;

	public State getCurrentState() {
		return currentState;
	}

	public void setCurrentState(State currentState) {
		this.currentState = currentState;
		currentState.setContext(this);
	}

	public void openDoor() {
		this.currentState.openDoor();
	}

	public void closeDoor() {
		this.currentState.closeDoor();
	}
}
 
package _20StatePattern;

/**
 * 场景类
 */
public class Client {

	public static void main(String[] args) {
		Context context = new Context();
//		context.setCurrentState(Context.OpenState);
//		context.closeDoor();
		context.setCurrentState(Context.CloseState);
		context.closeDoor();
	}

}

 

 5.状态模式的优点

  • 结构清晰:避免了过多的switch……case或者if……else语句,避免了程序的复杂性,提高系统的可维护性
  • 遵循设计原则:很好的体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,你要修改状态,只要修改一个子类就可以了
  • 封装性非常好:这也是状态模式的基本要求,状态变换放置到类的内部实现,外部的调用不知道内部如何实现和行为的变换

6.状态模式的缺点

状态模式既然有优点,那当然有缺点了。那就是子类会太多,也就是类膨胀,如果一个事物有很多状态也不稀奇,如果完全使用状态模式就会有太多的子类,不好管理,这个需要使用者衡量。

 

7.状态模式的注意事项

状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态不要超过5个。

分享到:
评论

相关推荐

    状态模式 State Pattern

    在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

    C#设计模式_设计模式_C#_

    创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式(Factory Method) 5. 原型模式(Prototype)结构型: 6.... 状态模式(State Pattern)

    C#设计模式(23种设计模式)

    创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3.... 4.... 5.... 6. 适配器模式(Adapter Pattern) 7. 桥接模式(Bridge Pattern) ... 状态模式(State Pattern) @Author kwming

    设计模式代码——c#

    C#设计模式(23种设计模式) 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式(Factory Method) 5. 原型模式(Prototype...23. 状态模式(State Pattern)

    23种设计模式 (创建型,结构型,行为型)

    创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3.... 4.... 5.... 6. 适配器模式(Adapter Pattern) 7. 桥接模式(Bridge Pattern) 8. 装饰模式(Decorator ... 状态模式(State Pattern)

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

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

    32种设计模式

    C# 32种设计模式: 创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式(Factory Method) ... 状态模式(State Pattern)

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

    允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

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

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

    com.designpattern.state_observer.rar

    用state模式和observer模式一些模式QQ在线状态 com.designpattern.state_observer.rar

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

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

    StatePattern.unitypackage

    StatePattern.unitypackage是一个unity演示的状态模式。有需要的同学可以自行下载。

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

    NULL 博文链接:https://zhangyan19870108.iteye.com/blog/1992409

    用Java实现23种设计模式

    状态模式(State Pattern) 空对象模式(Null Object Pattern) 策略模式(Strategy Pattern) 模板模式(Template Pattern) 访问者模式(Visitor Pattern) 4. J2EE 模式 MVC 模式(MVC Pattern) 业务代表...

    设计模式State模式源码

    State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了. 不只是根据状态,也有根据属性.如果...

    Java设计模式

    第 19 章 状态模式【STATE PATTERN】 ...................................................................................................... 236 第 20 章 原型模式【PROTOTYPE PATTERN】 ......................

    C#23种设计模式

    23. 状态模式(State Pattern) 工程结构 ├─01.Singleton │ ├─html │ └─MySingleton │ ├─bin │ │ └─Debug │ ├─obj │ │ └─Debug │ │ └─TempPE │ └─Properties ├─02....

    C#版 24种设计模式

    备忘录模式(Memento Pattern) 策略模式(Strategy Pattern) 抽象工厂模式(Abstract Factory Pattern) 代理模式(Proxy Pattern) ...装饰模式(Decorator Pattern) 状态模式(State Pattern) 组合模式(Composite Pattern)

    design-pattern-java.pdf

    十一个行为型模式 状态模式-State Pattern 处理对象的多种状态及其相互转换——状态模式(一) 处理对象的多种状态及其相互转换——状态模式(二) 处理对象的多种状态及其相互转换——状态模式(三) 处理对象的...

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册....状态模式(State) 策略模式(Strategy) 模板方法模式(Template Method) 访问者模式(Visitor)

Global site tag (gtag.js) - Google Analytics