状态模式(类的行为是基于它的状态改变的)
当代码中包含大量与对象状态有关的条件语句时,就可以使用状态模式
-
优点
1、结构清晰:状态模式将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
2、低耦合:将具体状态类引用到对象中会使得状态转换变得更加明确,且减少了对象间的相互依赖。
3、高扩展性:通过定义新的子类很容易地增加新的状态,有利于程序的扩展。 -
缺点
1、状态模式的使用会增加类与对象的个数。
2、状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
3、状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。 -
状态模式包含以下主要角色
环境类:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
抽象状态类:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
具体状态类:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。 -
例子:车辆有启动状态(startStatus)、行驶状态(driverStatus)、停车状态(stopStatus)、熄火状态(stopStatus);
抽象状态类
/**
* 状态接口
*/
public abstract class Status {
// 用于切换状态
Context context;
public void setContext(Context context) {
this.context = context;
}
// 启动行为
public abstract void startCar();
// 行驶行为
public abstract void driverCar();
// 停车行为
public abstract void stopCar();
// 熄火行为
public abstract void closeCar();
}
具体状态类
/**
* 启动状态
*/
public class StartStatus extends Status {
@Override
public void startCar() {
}
@Override
public void driverCar() {
super.context.setState(Context.DRIVER_STATUS);
System.out.println("切换至行驶状态!");
}
@Override
public void stopCar() {
}
@Override
public void closeCar() {
super.context.setState(Context.CLOSE_STATUS);
System.out.println("切换至熄火状态!");
}
}
/**
* 行驶状态
*/
public class DriverStatus extends Status {
@Override
public void startCar() {
}
@Override
public void driverCar() {
}
@Override
public void stopCar() {
super.context.setState(Context.STOP_STATUS);
System.out.println("切换至停车状态!");
}
@Override
public void closeCar() {
}
}
/**
* 停车状态
*/
public class StopStatus extends Status {
@Override
public void startCar() {
}
@Override
public void driverCar() {
}
@Override
public void stopCar() {
}
@Override
public void closeCar() {
super.context.setState(Context.CLOSE_STATUS);
System.out.println("切换至熄火状态!");
}
}
/**
* 熄火状态
*/
public class CloseStatus extends Status {
@Override
public void startCar() {
super.context.setState(Context.START_STATUS);
System.out.println("切换至启动状态!");
}
@Override
public void driverCar() {
}
@Override
public void stopCar() {
}
@Override
public void closeCar() {
}
}
环境类
/**
* 环境类
*/
public class Context {
public final static Status START_STATUS = new StartStatus();
public final static Status DRIVER_STATUS = new DriverStatus();
public final static Status STOP_STATUS = new StopStatus();
public final static Status CLOSE_STATUS = new CloseStatus();
private Status status;
public void setStatus(Status status) {
this.status = status;
this.status.setContext(this);
}
public void startCar() {
this.status.startCar();
}
public void driverCar() {
this.status.driverCar();
}
public void stopCar() {
this.status.stopCar();
}
public void closeCar() {
this.status.closeCar();
}
}
测试
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.setState(Context.START_STATUS);
context.startCar();
context.driverCar();
context.stopCar();
context.closeCar();
}
}
// 运行结果
切换至行驶状态!
切换至停车状态!
切换至熄火状态!