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();
}
}
}
}
运行截图
一个对象的状态指的就是这个对象的属性值集合,如果我么改变你这些属性的任意一个,那么这个对象的状态就发生了变化。一般的,调用一个对象的方法时都会改变这个对象的状态,并且往往会因为这个方法的调用来改变自己的属性。
为了处理状态之间的转变,我们可以由某个对象来引用状态对象的集合,通过应用状态模式,我们可以用一个状态类集合来表示对象的不同状态,并将一个跟状态相关的操作在这个集合中进行分配,这样一来就可以有效的简化当前系统了。
以上内容,整理自刘径舟,张玉华编著的《设计模式其实很简单》读书笔记,欢迎转载