现实生活中我们经常会碰到状态改变的场景,面对不同的场景我们会做出不同的处理。比如:
电梯的运行
• 维修、正常、自动关门、自动开门、向上运行、向下运行、消防状态
红绿灯
• 红灯、黄灯、绿灯
企业或政府系统
• 公文的审批状态
– 报销单据审批状态
– 假条审批
网上购物时,订单的状态
• 下单
• 已付款
• 已发货
• 送货中
• 已收货
状态模式
使用场景
本案例我们通过宾馆入住的情况来演示,宾馆房间的状态有这么几个:已预订,已入住,空闲。如果不用状态模式我们的实现如下:
if(state=="空闲"){ if(预订房间){ 预定操作; state="已预订"; }else if(住进房间){ 入住操作; state="已入住"; } }else if(“已预订"){ if(住进房间){ 入住操作; state="已入住"; }else if(取消预订){ 取消操作; state="空闲"; } }
这种实现中if语句过多,不便于维护修改。这时我们可以考虑用状态模式来实现。
状态模式实现
类图结构
核心:
用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题
实现代码
State
/** * State 接口 * @author 波波烤鸭 * @email dengpbs@163.com * */ public interface State { void handle(); }
State实现类
/** * 已预订状态 * @author 波波烤鸭 * @email dengpbs@163.com * */ public class BookedState implements State { @Override public void handle() { System.out.println("房间已预订!别人不能定!"); } }
/** * 已入住状态 * @author 波波烤鸭 * @email dengpbs@163.com * */ public class CheckedInState implements State { @Override public void handle() { System.out.println("房间已入住!请勿打扰!"); } }
/** * 空闲状态 * @author 波波烤鸭 * @email dengpbs@163.com * */ public class FreeState implements State { @Override public void handle() { System.out.println("房间空闲!!!没人住!"); } }
房间对象
/** * 房间对象 * @author 波波烤鸭 * @email dengpbs@163.com * */ public class HomeContext { //如果是银行系统,这个Context类就是账号。根据金额不同,切换不同的状态! private State state; public void setState(State s){ System.out.println("修改状态!"); state = s; state.handle(); } }
client
public class Client { public static void main(String[] args) { // 获取房间对象 HomeContext ctx = new HomeContext(); // 设置房间状态 ctx.setState(new FreeState()); ctx.setState(new BookedState()); } }
输出结果
修改状态! 房间空闲!!!没人住! 修改状态! 房间已预订!别人不能定!
开发中常见的场景:
银行系统中账号状态的管理
OA系统中公文状态的管理
酒店系统中,房间状态的管理
线程对象各状态之间的切换