设计模式 - 状态模式
状态模式:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
核心:当前状态决定当前行为,行为执行后又可能导致状态的转换
角色:
- Context上下文容器:维护所有的状态和行为,是面向客户的入口
- Status对象:保存状态对应的行为。
- Machine状态机:维护状态的转换关系
when(行为,状态) -> next状态:do(next行为)
由status对象在行为中完成状态转换
Context
// 上下文信息,用于维护所有状态对象以及当前状态信息,同时作为客户端的访问入口
public class Context implements IStatus{
// 更正一下设计模式之禅中对状态机的示例:其状态对象使用了final static,但是状态对象又持有了context对象引用,必然会出现并发问题
protected final IStatus OPEN = new OpenStatus(this);
protected final IStatus STOP_CLOSE = new StopStatus(this);
protected final IStatus RUN = new RunStatus(this);
private IStatus status = null;
public Context() {
this.status = STOP_CLOSE;
}
protected void setStatus(IStatus status) {this.status = status;}
// 具体行为委托给status对象执行
@Override
public void run() {this.status.run();}
@Override
public void stop() {this.status.stop();}
@Override
public void open() {this.status.open();}
@Override
public void close() {this.status.close();}
}
Status
// 抽象状态对象,提供公共的默认实现(由于在状态内部进行状态流转,因此还需持有context上下文信息)
public abstract class AbstractStatus implements IStatus{
protected Context context = null;
protected AbstractStatus(Context context){
this.context = context;
}
@Override
public void run() {System.out.println("command run - Do nothing!");}
@Override
public void stop() {System.out.println("command stop - Do nothing!");}
@Override
public void open() {System.out.println("command open - Do nothing!");}
@Override
public void close() {System.out.println("command close - Do nothing!");}
}
// 子类负责具体实现逻辑,重写该状态下支持的行为,并设置状态转换。
public class OpenStatus extends AbstractStatus{
public OpenStatus(Context context) {
super(context);
}
@Override
public void open() {
System.out.println("command open - keep open");
}
@Override
public void close() {
System.out.println("command close - close the door");
this.context.setStatus(this.context.STOP_CLOSE);
}
}
状态机实现状态模式
Context
// 用于维护当前状态信息,以及使用状态机完成状态转换,作为客户端的访问入口
public class Context implements IStatus {
private AbstractStatus status = null;
public Context() {
this.status = StatusMechine.STOP_CLOSE_STATUS;
}
protected void setStatus(AbstractStatus status) {
this.status = status;
}
// 将命令委托给具体的状态对象进行处理,并将当前状态和执行行为交由状态机完成状态转换
@Override
public void run() {
this.status.run();
this.status = StatusMechine.trans(this.status,StatusMechine.RUN_ACTION);
}
@Override
public void stop() {
this.status.stop();
this.status = StatusMechine.trans(this.status,StatusMechine.STOP_ACTION);
}
@Override
public void open() {
this.status.open();
this.status = StatusMechine.trans(this.status,StatusMechine.OPEN_ACTION);
}
@Override
public void close() {
this.status.close();
this.status = StatusMechine.trans(this.status,StatusMechine.CLOSE_ACTION);
}
}
StatusMechine
public class StatusMechine{
// 行为类型
protected final static String RUN_ACTION = "RUN";
protected final static String STOP_ACTION = "STOP";
protected final static String OPEN_ACTION = "OPEN";
protected final static String CLOSE_ACTION = "CLOSE";
// 状态类型
protected final static AbstractStatus OPEN_STATUS = new OpenStatus();
protected final static AbstractStatus STOP_CLOSE_STATUS = new StopStatus();
protected final static AbstractStatus RUN_STATUS = new RunStatus();
// 状态流转表
protected static Map<String,AbstractStatus> transMap = new HashMap<>();
// 状态转换
public static AbstractStatus trans(AbstractStatus status, String actions) {
String key = status.getStatusName() + actions;
return transMap.getOrDefault(key, status);
}
// 状态转换过程注册方法
protected static void registerStatusTrans(AbstractStatus status, String action, AbstractStatus nextStatus){
transMap.put(status.getStatusName() + action, nextStatus);
}
// 将状态的转换注册到状态机中
static {
StatusMechine.registerStatusTrans(StatusMechine.RUN_STATUS, StatusMechine.STOP_ACTION, StatusMechine.STOP_CLOSE_STATUS);
StatusMechine.registerStatusTrans(StatusMechine.STOP_CLOSE_STATUS, StatusMechine.RUN_ACTION, StatusMechine.RUN_STATUS);
StatusMechine.registerStatusTrans(StatusMechine.STOP_CLOSE_STATUS, StatusMechine.OPEN_ACTION, StatusMechine.OPEN_STATUS);
StatusMechine.registerStatusTrans(StatusMechine.OPEN_STATUS, StatusMechine.CLOSE_ACTION, StatusMechine.STOP_CLOSE_STATUS);
}
}
Status
// 抽象状态对象,提供公共的默认实现
public abstract class AbstractStatus implements IStatus {
public abstract String getStatusName();
@Override
public void run() {System.out.println("command run - Do nothing!");}
@Override
public void stop() {System.out.println("command stop - Do nothing!");}
@Override
public void open() {System.out.println("command open - Do nothing!");}
@Override
public void close() {System.out.println("command close - Do nothing!");}
}
// 具体实现子类,只需专注于具体指令的实现逻辑,而无需关心状态转换过程
public class OpenStatus extends AbstractStatus {
@Override
public String getStatusName() {
return "OPEN";
}
@Override
public void open() {
System.out.println("command open - keep open");
}
@Override
public void close() {
System.out.println("command close - close the door");
}
}
欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友
-- 星河有灿灿,愿与之辉