设计模式之状态模式

GOF对状态模式的定义是:当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。先看基本代码

/**
 * 
 * @author ricardo
 * @Time 上午12:31:24
 * @Function:抽象状态类
 *
 */
public abstract class State {
	public String stateName;
	public abstract void Handle(Context context);
}
具体状态类

public class ConcreteStaateA extends State {
	public ConcreteStaateA() {
		// TODO Auto-generated constructor stub
		stateName = "状态A";
	}
	
	@Override
	public void Handle(Context context) {
		// TODO Auto-generated method stub
		context.setState(new ConcreteStateB());
	}

}
public class ConcreteStateB extends State {

	public ConcreteStateB() {
		// TODO Auto-generated constructor stub
		stateName = "状态B";
	}
	
	@Override
	public void Handle(Context context) {
		// TODO Auto-generated method stub
		context.setState(new ConcreteStaateA());
	}

}
Context类

public class Context {
	private State state;
	public Context(State state) {
		this.state = state;
	}	
	public void setState(State state) {
		System.out.println("当前状态:" + this.state.stateName);
		this.state = state;
		System.out.println("状态变更为:" + this.state.stateName);
		System.out.println("************************");
	}	
	public void Request() {
		state.Handle(this);
	}
}

客户端代码

public class Client {
	public static void main(String[] args) {
		Context  context = new Context(new ConcreteStaateA());		
		context.Request();
		context.Request();
		context.Request();
	}
}

运行结果


状态模式的好处是将于特定状态相关的行为进行局部化,并且将不同状态的行为进行分割,也就是特定的与该状态相关的行为都放进一个对象,由于所有与状态相关的代码啦都存在于某个具体的状态类中,所以通过定义新的具体的状态类就能很容易的增加新的状态转换。

下面以模拟高铁运行状态为例

/**
 * 
 * @author ricardo
 * @Time 上午12:44:52
 * @Function:火车
 *
 */
public class Train {
	private State currentState;
	
	public Train() {
		currentState = new StartState();
	}
	
	private int speed;
	private boolean giveway = false;
	
	public void setState(State state) {
		currentState = state;
	}
	
	public int getSpeed() {
		return speed;
	}
	
	public void setSpeeed(int speed) {
		this.speed = speed;
	}

	public boolean isGiveway() {
		return giveway;
	}

	public void setGiveway(boolean giveway) {
		this.giveway = giveway;
	}
	
	public void Run() {
		currentState.Run(this);
	}
	
	
}
接下来是火车状态类

/**
 * 
 * @author ricardo
 * @Time 下午1:48:53
 * @Function:抽象状态
 *
 */
public abstract class State {
	public abstract void Run(Train train);
}
public class StartState extends State {

	@Override
	public void Run(Train train) {
		if(train.getSpeed()==0) {
			System.out.println("当前时速" + train.getSpeed()+"km/h,列车会开始启动!");
		}else {
			train.setState(new FastState());
			train.Run();
		}
	}

}

public class FastState extends State {

	@Override
	public void Run(Train train) {
		if(train.getSpeed() < 200) {
			System.out.println("当前时速" + train.getSpeed()+"km/h,列车正在加速!");
		}else {
			train.setState(new SlowState());
			train.Run();
		}
	}

}

public class SlowState extends State {

	@Override
	public void Run(Train train) {
		if(train.getSpeed() > 300) {
			System.out.println("当前时速" + train.getSpeed()+"km/h,列车正在减速!");
		}else {
			train.setState(new RunState());
			train.Run();
		}
	}

}

public class RunState extends State {

	@Override
	public void Run(Train train) {
		if(train.isGiveway()) {
			train.setState(new StopState());
			train.Run();
		}else {
			System.out.println("当前时速" + train.getSpeed()+"km/h,列车正在匀速行驶!");
		}
	}

}

public class StopState extends State {

	@Override
	public void Run(Train train) {
		System.out.println("当前时速" + train.getSpeed()+"km/h,列车减速,准备停车让行!");
	}

}
客户端代码

public class Client {
	public static void main(String[] args) {
		Train train = new Train();
		for(int i = 0;i<300;i+=50) {
			if(i == 250) {
				train.setGiveway(true);
				train.Run();
			}else {
				train.setSpeeed(i);
				train.Run();
			}
				
		}		
	}
}
运行截图



一个对象的状态指的就是这个对象的属性值集合,如果我么改变你这些属性的任意一个,那么这个对象的状态就发生了变化。一般的,调用一个对象的方法时都会改变这个对象的状态,并且往往会因为这个方法的调用来改变自己的属性。

为了处理状态之间的转变,我们可以由某个对象来引用状态对象的集合,通过应用状态模式,我们可以用一个状态类集合来表示对象的不同状态,并将一个跟状态相关的操作在这个集合中进行分配,这样一来就可以有效的简化当前系统了。

以上内容,整理自刘径舟,张玉华编著的《设计模式其实很简单》读书笔记,欢迎转载



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值