描述
- 当程序要进行多种复杂的判断,进行状态切换时,可以把复杂的判断提取到各自的状态中。
- 比如提到材料时,材料要经过待审核,审核中,审核通过,驳回等状态,每个状态需要的条件,可以封装在各自的状态。
角色
- 环境角色:客户需要的接口,维护当前状态。
- 抽象状态角色:接口或抽象类,封装环境对象中的状态行为。
- 具体状态角色:实现抽象状态,具体的某种状态行为。
实现
public class Test {
public static void main(String[] args) {
CurrentStatus currentStatus = new CurrentStatus();
currentStatus.setStatus(CurrentStatus.TO_BE_REVIEWED);
currentStatus.create();
currentStatus.examine();
currentStatus.pass();
currentStatus.reject();
}
}
abstract class AbstractStatus {
CurrentStatus currentStatus;
public void setCurrentStatus(CurrentStatus currentStatus) {
this.currentStatus = currentStatus;
}
abstract void create();
abstract void examine();
abstract void pass();
abstract void reject();
}
class ToBeReviewed extends AbstractStatus {
@Override
void create() {
System.out.println("创建申请单,当前为待审核状态");
}
@Override
void examine() {
System.out.println("进行审核,转换为审核中状态");
super.currentStatus.setStatus(CurrentStatus.UNDER_REVIEW);
}
@Override
void pass() {
}
@Override
void reject() {
}
}
class UnderReview extends AbstractStatus {
@Override
void create() {
}
@Override
void examine() {
System.out.println("当前已经是审核中状态");
}
@Override
void pass() {
System.out.println("审核通过,转为审核通过状态");
super.currentStatus.setStatus(CurrentStatus.APPROVED);
}
@Override
void reject() {
System.out.println("转为驳回状态");
super.currentStatus.setStatus(CurrentStatus.REJECTED);
}
}
class Approved extends AbstractStatus {
@Override
void create() {
}
@Override
void examine() {
}
@Override
void pass() {
}
@Override
void reject() {
System.out.println("转为驳回状态");
super.currentStatus.setStatus(CurrentStatus.REJECTED);
}
}
class Rejected extends AbstractStatus {
@Override
void create() {
System.out.println("驳回,转待审核状态");
super.currentStatus.setStatus(CurrentStatus.TO_BE_REVIEWED);
}
@Override
void examine() {
}
@Override
void pass() {
}
@Override
void reject() {
}
}
class CurrentStatus extends AbstractStatus {
protected static final ToBeReviewed TO_BE_REVIEWED = new ToBeReviewed();
protected static final UnderReview UNDER_REVIEW = new UnderReview();
protected static final Approved APPROVED = new Approved();
protected static final Rejected REJECTED = new Rejected();
private AbstractStatus status;
public void setStatus(AbstractStatus status) {
this.status = status;
this.status.setCurrentStatus(this);
}
@Override
void create() {
status.create();
}
@Override
void examine() {
status.examine();
}
@Override
void pass() {
status.pass();
}
@Override
void reject() {
status.reject();
}
}
优点
- 状态的行为封装到一个类中,方便添加新的状态。
- 状态逻辑转换行为聚合在一块,而不是一大块 if else 逻辑判断语句。
缺点
- 类数量增多,每增加一个状态,就需要一个状态类。
- 复杂度提高,使用不当容易导致程序结构混乱。
- 增加新类也需要更改原有代码,不符合开闭原则。
使用场景
- 当一个对象切换状态时,需要经过大量的 if else 逻辑判断条件时,可以考虑使用状态模式。
- 当一个对象的行为依赖状态,且必须在运行时改变它的状态,可以考虑使用状态模式。