天天看点

Java设计模式之状态模式

状态模式定义,允许对象在自己内部状态改变时改变它的行为,对象看起来就像是修改了它的类。

该描述第一部分意思是,这个模式将状态封装进了一个独立的类,并将动作委托到对象的当前状态的状态对象。第二个部分意思就是,让客户感觉使用了对象能够改变它的行为,但是实际上这种设计模式 使用组合通过简单引用不同状态对象来造成类的改变假象。状态模式封装了一组行为。

状态模式类图

Context:是一个上下文类,可以拥有一些内部状态,并且将多个状态对象组合结合在一起。

State接口:定义了所有状态具有的共同操作,一般可以将该接口的方法和context设置一样的。

ConcreteStateA:实现了具体的状态对象,处理来自context的请求,凡是context中调用request方法,都会将该方法委托到具体的状态对象来处理。

通过在context来利用组合和多态,从而在实际的状态改变中将行为委托到具体的实现状态类中,状态模式将每一个状态的行为具体到局部化到该状态所对象的类中,免去了大量的if判断,它可以让每一个状态“对修改关闭”,让context“对扩展开放”。

一般来说,当状态转换是固定的时候,一般将状态的改变放置到context中。当转换是动态的时候,则将状态的改变放置到状态类中,状态类中应该有context的引用。

实例代码

一个糖果机,有四种不同的状态,根据不同的行为就会转换成不同的状态。

状态State接口

package com.whut.state;

publicinterface State {

void insertQuarter();

void ejectQuarter();

void turnCrank();

void dispense();

}

糖果机类(context)

//状态模式

public class GumballMachine {

private State soleOutState;

private State noQuarterState;

private State hasQuarterState;

private State soldState;

private State winnerState;

private State state=soleOutState;

private int count=0;

public GumballMachine(int count)

{

soleOutState=new SoldOutState(this);

noQuarterState=new NoQuarterState(this);

hasQuarterState=new HasQuarterState(this);

soldState=new SoldState(this);

winnerState=new WinnerState(this);

this.count=count;

if(count>0)

state=noQuarterState;

//投入25分的动作

public void insertQuarter()

state.insertQuarter();

//退回25分的动作

public void ejectQuarter()

state.ejectQuarter();

//转动曲柄

public void turnCrank()

state.turnCrank();

state.dispense();

//释放糖果

public void releaseBall()

System.out.println("A gunmball comes rolling out the slot from machine");

if(count!=0)

count=count-1;

//打印机器当前状态

@Override

public String toString()

return"-----------"+"\nThe machine state:"+state.toString()+"\ncount="+count+"\n-----------";

//设置状态

publicvoid setState(State st)

this.state=st;

//获取状态

public State getSoleOutState() {

return soleOutState;

public State getNoQuarterState() {

return noQuarterState;

public State getHasQuarterState() {

return hasQuarterState;

public State getSoldState() {

return soldState;

//获取总的数目

publicint getCount() {

return count;

public State getWinnerState() {

return winnerState;

状态实现类:

public class NoQuarterState implements State {

private GumballMachine gumballMachine;

public NoQuarterState(GumballMachine gumballMachine)

this.gumballMachine=gumballMachine;

publicvoid insertQuarter() {

System.out.println("You inserted a quarter");

gumballMachine.setState(gumballMachine.getHasQuarterState());

publicvoid ejectQuarter() {

System.out.println("You haven't inserted a quarter");

publicvoid turnCrank() {

System.out.println("You turned,but there's no quarter");

publicvoid dispense() {

System.out.println("You need to pay a quarter first");

状态模式与策略模式比较

状态模式,将一群行为封装到状态对象中,Context的行为随时可委托到那些状态对象中的一个。对象的状态改变是在内部实现的,游走于对象集合中,用户察觉不到,只是通过触发相应的行为。状态模式利用许多个不同的状态对象作为其成员属性进行组合,任何状态的改变都是事先定义好的。

策略模式,客户往往是主动指定Context所要组合的策略对象是哪一个,使得能够在运行的时候改变策略即对象的行为。可以将状态模式想成是不用在context中放置许多条件判断语句的替代方法,通过将行为包装进状态对象后,可以通过在context内部来改变状态对象来改变context的行为。策略模式通常是利用行为或者策略类来配置context类的。

本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1177995