最近发现项目中的判断太多,大量的if-else结构,想着重构下,于是接触到了状态模式。
这种设计模式就是java多态的体现,没有想象的那么神奇。
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
即
1、有一个对象,它是有状态的。
2、这个对象在状态不同的时候,行为不一样。
3、这些状态是可以切换的,而非毫无关系。
图中包含三个角色。
Context:它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。
State:状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。
ConcreteState:具体状态,实现相关行为的具体状态类。
其他解释
环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
个人还是喜欢把环境角色context带入接口的方法参数中,这样逻辑更清楚;
另外的方式是把context放入各个具体状态角色的构造方法中,当实例化context的时候,通过具体状态的构造方法加载此context实例到具体状态角色中
举例一
本例子模拟购物的整个过程,包括下单,付款,收货,评价,退款,结束等。
状态接口
public interface Event { //下单 void order(Shopping shopping,Boolean isConfirm) ; //付款 void pay(Shopping shopping,Boolean isConfirm); //签收 void receive(Shopping shopping,Boolean isConfirm); //评价 void evaluate(Shopping shopping,Boolean isConfirm); //订单结束 void finish(Shopping shopping,Boolean isConfirm); //退款 void refund(Shopping shopping,Boolean isConfirm); }
抽象类主要处理异常的情况,即用户重复提交某个状态时出现
public class AbstractEvent implements Event { @Override public void order(Shopping shopping, Boolean isConfirm) { System.out.println("亲亲,下单异常"); } @Override public void pay(Shopping shopping, Boolean isConfirm) { System.out.println("亲亲,支付异常"); } @Override public void receive(Shopping shopping, Boolean isConfirm) { System.out.println("亲亲,接收异常"); } @Override public void evaluate(Shopping shopping, Boolean isConfirm) { System.out.println("亲亲,评价异常"); } @Override public void finish(Shopping shopping, Boolean isConfirm) { System.out.println("亲亲,结束操作流程错误"); } @Override public void refund(Shopping shopping, Boolean isConfirm) { System.out.println("您的订单已经退款,请不要重复提交"); } }
具体状态角色 - 下单
public class Order extends AbstractEvent { @Override public void order(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("恭喜您,下单成功"); shopping.setEvent(Shopping.PAY_STATE);//确定下单,进入支付页面 }else { System.out.println("订单页面取消成功,回到主页面"); shopping.setEvent(Shopping.REFUND); } } }
具体状态角色 - 支付
public class Pay extends AbstractEvent { @Override public void pay(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("恭喜您,支付成功"); shopping.setEvent(Shopping.RECEIVE_STATE);//进入收货阶段 }else { System.out.println("支付页面,取消订单成功"); shopping.setEvent(Shopping.REFUND); } } }
具体状态角色 - 接收
public class Receive extends AbstractEvent { @Override public void receive(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("亲,签收物品成功,期待下次与您再次相见"); shopping.setEvent(Shopping.EVALUATE_STATE); }else { System.out.println("亲,签收阶段退款成功"); shopping.setEvent(Shopping.REFUND); } } }
具体状态角色 - 评价
public class Evaluate extends AbstractEvent { @Override public void evaluate(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("评价商品成功"); shopping.setEvent(Shopping.FINISH_STATE); }else { System.out.println("评价阶段,退款成功"); shopping.setEvent(Shopping.REFUND); } } }
具体状态角色 - 完成
public class Finish extends AbstractEvent { @Override public void finish(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("订单结束,感谢您的光临"); }else { System.out.println("亲爱的客人,请您分享使用心得"); } } }
具体状态角色 - 退款
public class Refund extends AbstractEvent { @Override public void refund(Shopping shopping, Boolean isConfirm) { if(isConfirm){ System.out.println("抱歉客官,给您带来不好的购物体验了,已为您退款,请见谅"); shopping.setEvent(Shopping.FINISH_STATE); } } }
环境角色,有状态的对象 - 购物对象
public class Shopping { public static final Event ORDER_STATE = new Order(); public static final Event PAY_STATE = new Pay(); public static final Event RECEIVE_STATE = new Receive(); public static final Event EVALUATE_STATE = new Evaluate(); public static final Event FINISH_STATE = new Finish(); public static final Event REFUND = new Refund(); //状态记录,默认进入下单状态 private Event event = ORDER_STATE; public Event getEvent() { return event; } public void setEvent(Event event) { this.event = event; } public void startOrder(Boolean isConfirm){ event.order(this,isConfirm); } public void startPay(Boolean isConfirm){ event.pay(this,isConfirm); } public void startReceive(Boolean isConfirm){ event.receive(this,isConfirm); } public void startEvaluate(Boolean isConfirm){ event.evaluate(this,isConfirm); } public void startFinish(Boolean isConfirm){ event.finish(this,isConfirm); } public void startRefund(Boolean isConfirm){ event.refund(this,isConfirm); } }
客户启动段
public class Client { public static void main(String[] args) { Shopping shopping = new Shopping(); //下单成功 shopping.startOrder(true); shopping.startOrder(true); shopping.startOrder(true); shopping.startOrder(true); shopping.startOrder(true); shopping.startPay(true); shopping.startReceive(false); shopping.startRefund(true); shopping.startEvaluate(true); shopping.startFinish(true); } }
运行结果:
状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换,又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。