设计模式---状态模式

Posted nijunyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式---状态模式相关的知识,希望对你有一定的参考价值。

问题场景:

对于一个订单在不同的阶段有不同的状态,不同的状态处理逻辑也不一样。如果使用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。符合“开闭原则”。容易增删状态。

但是会产生很多类,每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护成本。

当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑使用状态模式

 

 

 

 

 

 

以上是关于设计模式---状态模式的主要内容,如果未能解决你的问题,请参考以下文章

Golang设计模式——状态模式

设计模式---状态变化模式之state状态模式(State)

设计模式 --- 状态模式

23种设计模式(十七)——状态模式状态变化

设计模式状态模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

设计模式之状态模式