在我们软件开发的过程中,有许多对象是有状态的。而对象的行为会随着状态的改变而发生改变。例如开发一个电梯类,电梯有开门、关门、停止、运行等行为,同时电梯也会有开门状态、关门状态、停止状态、运行状态等不同的状态。电梯处于不同的状态时,对不同的行为会做出不同的动作。如当电梯处于开门状态时,电梯可以做关门动作;开门状态时,电梯一定是停止的,所以此时停止动作不会发生任何行为;开门状态时,电梯不能运行,所以运行动作也不会发生任何行为。如果我们使用条件判断语句实现上述逻辑,会出现大量的if else判断,或者switch case 语句。而且当需要增加一个状态时,这些条件判断语句都需要修改。例如增加一个维修状态,不仅会修改原有的if else,还有引入维修状态的判断和执行逻辑。
为了解决上面说的不同状态不同行为的问题,引出了状态模式。一个对象在某一时刻只有一种状态,根据对象的状态决定对象的某一个行为的具体动作。
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
电梯类:
/**
* 环境类:定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。
*/
public class Lift {
// 定义出所有的电梯状态
public static final LiftState OPENNINGSTATE = new OpeningState();
public static final LiftState CLOSEINGSTATE = new ClosingState();
public static final LiftState RUNNINGSTATE = new RunningState();
public static final LiftState STOPPINGSTATE = new StoppingState();
// 定义一个当前电梯状态
private LiftState liftState;
public boolean open() {
return liftState.open(this);
}
public boolean close() {
return liftState.close(this);
}
public boolean run() {
return liftState.run(this);
}
public boolean stop() {
return liftState.stop(this);
}
public LiftState getLiftState() {
return liftState;
}
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
}
}
状态接口:
/**
*
* 定义一个电梯的状态接口
*/
public abstract class LiftState {
// 首先电梯门开启动作
abstract boolean open(Lift lift);
// 电梯门有开启,那当然也就有关闭了
abstract boolean close(Lift lift);
// 电梯要能上能下,跑起来
abstract boolean run(Lift lift);
// 电梯还要能停下来,停不下来那就扯淡了
abstract boolean stop(Lift lift);
abstract LiftState getState();
}
具体状态类:
open状态类:
/**
* 在电梯门开启的状态下能做什么事情
*/
public class OpeningState extends LiftState {
@Override
boolean open(Lift lift) {
System.out.println("The lift is opening now, no need to reopen.");
return false;
}
/**
* 开启当然可以关闭了,我就想测试一下电梯门开关功能
*/
@Override
boolean close(Lift lift) {
System.out.println("OpeningState to close the lift door. The lift is closed now.");
//状态修改
lift.setLiftState(Lift.CLOSEINGSTATE);
return true;
}
@Override
boolean run(Lift lift) {
System.out.println("The lift is opening, can not run!!");
return false;
}
@Override
boolean stop(Lift lift) {
System.out.println("The lift is opening, of course it is stopped.");
return false;
}
@Override
LiftState getState() {
return Lift.OPENNINGSTATE;
}
}
close状态类:
public class ClosingState extends LiftState {
@Override
boolean open(Lift lift) {
System.out.println("ClosingState to open the lift door. The lift is open now.");
//状态修改
lift.setLiftState(Lift.OPENNINGSTATE);
return true;
}
@Override
boolean close(Lift lift) {
System.out.println("The lift is closed now, have no need to reclose!!");
return false;
}
@Override
boolean run(Lift lift) {
System.out.println("ClosingState to run the lift. The lift is running now.");
lift.setLiftState(Lift.RUNNINGSTATE);
return true;
}
@Override
boolean stop(Lift lift) {
System.out.println("ClosingState to stop the lift. The lift is stopped now.");
lift.setLiftState(Lift.STOPPINGSTATE);
return true;
}
@Override
LiftState getState() {
return Lift.CLOSEINGSTATE;
}
}
stop状态类:
public class StoppingState extends LiftState {
@Override
boolean open(Lift lift) {
System.out.println("StoppingState to open the lift door. the lift is open now.");
lift.setLiftState(Lift.OPENNINGSTATE);
return true;
}
@Override
boolean close(Lift lift) {
//停止状态关门?电梯门本来就是关着的!
System.out.println(" the lift is closed, have no need to reclose!");
return false;
}
@Override
boolean run(Lift lift) {
System.out.println("StoppingState to run the lift. the lift is running now.");
lift.setLiftState(Lift.RUNNINGSTATE);
return true;
}
@Override
boolean stop(Lift lift) {
System.out.println("the lift is stop now, have no need to restop!");
return false;
}
@Override
LiftState getState() {
// TODO Auto-generated method stub
return Lift.STOPPINGSTATE;
}
}
run状态类:
public class RunningState extends LiftState {
@Override
boolean open(Lift lift) {
System.out.println("The lift is running, can not be opened!!");
return false;
}
@Override
boolean close(Lift lift) {
System.out.println("The lift is running, the lift door is closed. have no need to reclose.");
return false;
}
@Override
boolean run(Lift lift) {
System.out.println("The lift is running. have no need to rerun.");
return false;
}
@Override
boolean stop(Lift lift) {
System.out.println("RunningState to stop the lift. The lift is stopped now.");
lift.setLiftState(Lift.STOPPINGSTATE);
return true;
}
@Override
LiftState getState() {
return Lift.RUNNINGSTATE;
}
}
测试类:
public class Client {
public static void main(String[] args) {
Lift context = new Lift();
context.setLiftState(Lift.CLOSEINGSTATE);
context.open();
context.close();
context.run();
context.stop();
context.run();
context.open();
context.open();
context.stop();
context.open();
}
}