电梯功能,电梯状态分为:开门、关门、运行、停止4个状态,不同的状态下支持的操作是不同的。
/**
* 电梯接口
*/
public interface ILift {
int OPENING_STATE = 1;
int CLOSING_STATE = 2;
int RUNNING_STATE = 3;
int STOPPING_STATE = 4;
// 设置电梯状态的功能
void setState(int state);
void open();
void close();
void run();
void stop();
}
/**
* 电梯类
*/
public class Lift implements ILift {
private int state;
@Override
public void setState(int state) {
this.state = state;
}
//执行关门动作
@Override
public void close() {
switch (this.state) {
case OPENING_STATE:
System.out.println("电梯关门了。。。");//只有开门状态可以关闭电梯门,可以对应电梯状态表来看
this.setState(CLOSING_STATE);//关门之后电梯就是关闭状态了
break;
case CLOSING_STATE:
//do nothing //已经是关门状态,不能关门
break;
case RUNNING_STATE:
//do nothing //运行时电梯门是关着的,不能关门
break;
case STOPPING_STATE:
//do nothing //停止时电梯也是关着的,不能关门
break;
}
}
//执行开门动作
@Override
public void open() {
switch (this.state) {
case OPENING_STATE://门已经开了,不能再开门了
//do nothing
break;
case CLOSING_STATE://关门状态,门打开:
System.out.println("电梯门打开了。。。");
this.setState(OPENING_STATE);
break;
case RUNNING_STATE:
//do nothing 运行时电梯不能开门
break;
case STOPPING_STATE:
System.out.println("电梯门开了。。。");//电梯停了,可以开门了
this.setState(OPENING_STATE);
break;
}
}
//执行运行动作
@Override
public void run() {
switch (this.state) {
case OPENING_STATE://电梯不能开着门就走
//do nothing
break;
case CLOSING_STATE://门关了,可以运行了
System.out.println("电梯开始运行了。。。");
this.setState(RUNNING_STATE);//现在是运行状态
break;
case RUNNING_STATE:
//do nothing 已经是运行状态了
break;
case STOPPING_STATE:
System.out.println("电梯开始运行了。。。");
this.setState(RUNNING_STATE);
break;
}
}
//执行停止动作
@Override
public void stop() {
switch (this.state) {
case OPENING_STATE: //开门的电梯已经是是停止的了(正常情况下)
//do nothing
break;
case CLOSING_STATE://关门时才可以停止
System.out.println("电梯停止了。。。");
this.setState(STOPPING_STATE);
break;
case RUNNING_STATE://运行时当然可以停止了
System.out.println("电梯停止了。。。");
this.setState(STOPPING_STATE);
break;
case STOPPING_STATE:
//do nothing
break;
}
}
}
Lift类中的每个方法都会出现大量的switch或者 if else,这看上去代码不够优雅。
对有状态的对象,把复杂的判断逻辑提取到不同的状态对象中,运行状态对象在其内部状态发生改变时改变其行为。
状态模式就是把原来的case或者if else if 分支都抽象成一个对象。
/**
* 抽象状态类
*/
public abstract class LiftState {
// 用于被子类继承
protected Context context;
public void setContext(Context context) {
this.context = context;
}
public abstract void open();
public abstract void close();
public abstract void run();
public abstract void stop();
}
/**
* 开启状态
*/
public class OpeningState extends LiftState {
@Override
public void open() {
System.out.println("电梯开启...");
}
@Override
public void close() {
// 修改了liftState的指向对象
super.context.setLiftState(Context.CLOSING_STATE);
// 调用修改后的状态对应的方法
super.context.close();
}
@Override
public void run() {
// 什么都不做
}
@Override
public void stop() {
// 什么都不做
}
}
---
/**
* 关闭状态
*/
public class ClosingState extends LiftState{
@Override
public void open() {
super.context.setLiftState(Context.OPENING_STATE);
super.context.open();
}
@Override
public void close() {
System.out.println("电梯关门了...");
}
@Override
public void run() {
super.context.setLiftState(Context.RUNNING_STATE);
super.context.run();
}
@Override
public void stop() {
super.context.setLiftState(Context.STOPPING_STATE);
super.context.stop();
}
}
---
/**
* 运行状态
*/
public class RunningState extends LiftState{
@Override
public void open() {
// do nothing
}
@Override
public void close() {
// do nothing
}
@Override
public void run() {
System.out.println("电梯正在运行...");
}
@Override
public void stop() {
super.context.setLiftState(Context.STOPPING_STATE);
super.context.stop();
}
}
---
/**
* 停止状态
*/
public class StoppingState extends LiftState{
@Override
public void open() {
super.context.setLiftState(Context.OPENING_STATE);
super.context.open();
}
@Override
public void close() {
super.context.setLiftState(Context.CLOSING_STATE);
super.context.close();
}
@Override
public void run() {
super.context.setLiftState(Context.RUNNING_STATE);
super.context.run();
}
@Override
public void stop() {
System.out.println("电梯停止了...");
}
}
然后引入一个上下文作为代理,
/**
* 环境角色类
*/
public class Context {
public final static OpeningState OPENING_STATE = new OpeningState();
public final static ClosingState CLOSING_STATE = new ClosingState();
public final static RunningState RUNNING_STATE = new RunningState();
public final static StoppingState STOPPING_STATE = new StoppingState();
private LiftState liftState;
public LiftState getLiftState() {
return liftState;
}
public void setLiftState(LiftState liftState) {
this.liftState = liftState;
this.liftState.setContext(this);
}
public void open() {
this.liftState.open();
}
public void close() {
this.liftState.close();
}
public void run() {
this.liftState.run();
}
public void stop() {
this.liftState.stop();
}
}
客户端的操作都要使用上下文来操作。
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setLiftState(new RunningState());
context.open();
context.close();
context.run();
context.stop();
}
}
优点:
缺点: