设计模式---状态模式
问题场景:
对于一个订单在不同的阶段有不同的状态,不同的状态处理逻辑也不一样。如果使用if/esle来判断订单状态,从而实现不同的操作。这样难以应对变化,增加一个状态,我们就需要增加一个分之,还可能影响原有逻辑判断。
if(待支付){
xxx
}else if(已付款){
xxxx
}else if(代发货){
xxxx
}else if(已发货){
xxxx
}
……
状态模式主要用来解决对象在多种状态转换时,需要对外 输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。
在状态模式中,我们需要创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
比如上述订单的各种状态:待付款,已付款,待发货,已发货,已签收等。
按照状态模式来设计,首先创建一个State接口以及他的各种实现,每个实现类对于接口的抽象方法都有不同的处理逻辑,并且根据具体的业务流程会修改Context对象里面的状态。Context类聚合State并且与State的实现相互关联。
类图如下:
基于此类图实现代码:
————–
状态:
State:
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public abstract class State { abstract void pay(); abstract void checkPay(); abstract void deliverGoods(); abstract void toBeReceive(); abstract void receive(); abstract void other(); }
ToBePayState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class ToBePayState extends State { private OrderContext orderContext; public ToBePayState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { System.out.println("用户已支付..."); orderContext.setState(orderContext.getPaidState()); } @Override void checkPay() { } @Override void deliverGoods() { System.out.println("未付款,不能发货"); } @Override void toBeReceive() { } @Override void receive() { } @Override void other() { } }
PaidState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class PaidState extends State { private OrderContext orderContext; public PaidState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { System.out.println("已支付"); } @Override void checkPay() { System.out.println("确认支付成功..."); orderContext.setState(orderContext.getDeliverGoodsState()); } @Override void deliverGoods() { System.out.println("准备发货"); } @Override void toBeReceive() { } @Override void receive() { } @Override void other() { } }
DeliverGoodsState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class DeliverGoodsState extends State { private OrderContext orderContext; public DeliverGoodsState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { System.out.println("已支付"); } @Override void checkPay() { } @Override void deliverGoods() { System.out.println("物流发货..."); orderContext.setState(orderContext.getGoodsReceivedState()); } @Override void toBeReceive() { } @Override void receive() { } @Override void other() { } }
GoodsToBeReceivedState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class GoodsToBeReceivedState extends State { private OrderContext orderContext; public GoodsToBeReceivedState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { } @Override void checkPay() { } @Override void deliverGoods() { } @Override void toBeReceive() { System.out.println("运输中..."); orderContext.setState(orderContext.getGoodsReceivedState()); } @Override void receive() { } @Override void other() { } }
GoodsReceivedState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class GoodsReceivedState extends State { private OrderContext orderContext; public GoodsReceivedState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { } @Override void checkPay() { } @Override void deliverGoods() { } @Override void toBeReceive() { } @Override void receive() { System.out.println("签收货物..."); orderContext.setState(orderContext.getSuccessState()); } @Override void other() { } }
SuccessState
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class SuccessState extends State { private OrderContext orderContext; public SuccessState(OrderContext orderContext) { this.orderContext = orderContext; } @Override void pay() { System.out.println("已支付"); } @Override void checkPay() { } @Override void deliverGoods() { System.out.println("已收货"); } @Override void toBeReceive() { } @Override void receive() { } @Override void other() { System.out.println("用户积分增加..."); } }
————–
context
OrderContext
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class OrderContext { private State state; private ToBePayState toBePayState = new ToBePayState(this); private PaidState paidState = new PaidState(this); private DeliverGoodsState deliverGoodsState = new DeliverGoodsState(this); private GoodsToBeReceivedState goodsToBeReceivedState = new GoodsToBeReceivedState(this); private GoodsReceivedState goodsReceivedState = new GoodsReceivedState(this); private SuccessState successState = new SuccessState(this); //初始化订单的时候状态设置待付款 public OrderContext(String userName) { System.out.println("用户 " + userName +" 下单"); this.state = toBePayState; } public void toPay(){ toBePayState.pay(); } public void checkPay(){ paidState.checkPay(); } public void deliverGoods(){ deliverGoodsState.deliverGoods(); } public void toBeReceive(){ goodsToBeReceivedState.toBeReceive(); } public void receive(){ goodsReceivedState.receive(); } public void end(){ successState.other(); } public State getState() { return state; } public void setState(State state) { this.state = state; } public ToBePayState getToBePayState() { return toBePayState; } public void setToBePayState(ToBePayState toBePayState) { this.toBePayState = toBePayState; } public PaidState getPaidState() { return paidState; } public void setPaidState(PaidState paidState) { this.paidState = paidState; } public DeliverGoodsState getDeliverGoodsState() { return deliverGoodsState; } public void setDeliverGoodsState(DeliverGoodsState deliverGoodsState) { this.deliverGoodsState = deliverGoodsState; } public SuccessState getSuccessState() { return successState; } public void setSuccessState(SuccessState successState) { this.successState = successState; } public GoodsToBeReceivedState getGoodsToBeReceivedState() { return goodsToBeReceivedState; } public void setGoodsToBeReceivedState(GoodsToBeReceivedState goodsToBeReceivedState) { this.goodsToBeReceivedState = goodsToBeReceivedState; } public GoodsReceivedState getGoodsReceivedState() { return goodsReceivedState; } public void setGoodsReceivedState(GoodsReceivedState goodsReceivedState) { this.goodsReceivedState = goodsReceivedState; } }
测试:
package com.nijunyang.designpatterns.state; /** * @author: create by nijunyang * @date:2019/9/22 */ public class Test { public static void main(String[] args) throws InterruptedException { for(int i = 0; i < 5; i++) { OrderContext orderContext = new OrderContext("user" + i); orderContext.toPay(); orderContext.checkPay(); orderContext.deliverGoods(); orderContext.toBeReceive(); orderContext.receive(); orderContext.end(); System.out.println("---------"); Thread.sleep(1000); } } }
以上代码的实现都是按照最简单的正常流程走的,实际上,不同State的实现类里面不同的方法还会操作修改状态,这个就要根据实际的业务流程来控制了。
简单总结:
使用状态模式代码有很强的可读性。状态模式将每个状态的行为封装到对应的一个类中方便维护。
减少if/else。符合“开闭原则”。容易增删状态。
但是会产生很多类,每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护成本。
当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑使用状态模式