状态模式简单实现

工作过程中,我们经常遇到一些复杂的状态转换的问题,如果我们使用传统的方式来处理状态转换,相信状态上了10多个以上的时候,每个地方都是If else判断测试的时候,你就知道痛苦了,在处理订单状态时候,10多个状态也是常有的事情,我们可以借助状态模式来解决这个问题,在多次项目过程中,使用该模式之后明显感觉状态处理要清晰得多,即使中间涉及到删减或增加一些状态 中间状态,该模式处理起来游刃有余。

  状态转换,绝大多数是由于事件触发引起的,currentStatus___event___nextStatus,即在当前状态下发生了一个事件促使状态转移到下一个状态,设计模式中详细进行了阐述,这里我只给一个简单的实现。


public enum Status {
    wait(1) {// 等待发送状态
        @Override
        protected void initMap() {
            addEventTansferMap(Event.send, sended);
        }

    },
    sended(2) {// 已经发送状态
        @Override
        protected void initMap() {
            addEventTansferMap(Event.confirm, confirmed);
        }
    },
    confirmed(3) {// 已经确认状态
        @Override
        protected void initMap() {}
    };

    /***************************************************************************
     *
     * 共有方法
     *
     * *******************************************************************************
     */

    private Status(int value) {
        this.value = value;
    }
    
    public int getValue(){
        return this.value;
    }

    protected abstract void initMap();// 初始化映射事件状态映射关系

    /**
     * 根据发生的事件得到下一个状态
     *
     * @param e
     *            事件
     * @return 下一个状态,如果该事件没有造成状态改变,返回null
     */
    public final Status next(Event e) {
        init();
        return translations.get(e);
    }
    
    /**
     * 初始化事件与状态转换映射
     */
    private void init() {
        if (false == initialed) {// double checked
            synchronized (LOCK) {
                if (false == initialed) {
                    translations = new EnumMap<Event, Status>(Event.class);
                    initMap();
                    initialed = true;
                }
            }
        }
    }
    /**
     *
     * @param e 发生的事件
     * @param s 事件发生后转移到的状态
     */
    protected void addEventTansferMap(Event e,Status s){
        translations.put(e, s);
    }

    private Map<Event, Status> translations;    //事件状态映射
    private boolean initialed = false;    // 映射是否已经初始化
    private int value;    //状态原始值


    private Object LOCK = new Object();

    
    
    
    
    
    
    // 事件枚举,可以单独作为一个类
    public enum Event {
        send, // 发送事件
        confirm;// 确认事件
    }

    public static void main(String[] args) {
        System.out.println("下一个状态:" + wait.next(Event.send));
        System.out.println(sended.next(Event.confirm));
        System.out.println(wait.next(Event.confirm));
    }

}

 由以上实现可以知道,新增一个状态,新增一个事件都非常简单。第一步,在Event中新增一个事件,第二步,在Status中新增一个状态 ,第三步,新增事件和状态转移映射(覆盖initMap即可)。

在使用时只需要使用当前的发生的事件作为参数调用next即可以得到下一个状态,非常简单。

posted @ 2008-04-25 15:43  lovingprince  阅读(229)  评论(0编辑  收藏  举报