状态模式简单实现
工作過(guò)程中,我們經(jīng)常遇到一些復(fù)雜的狀態(tài)轉(zhuǎn)換的問(wèn)題,如果我們使用傳統(tǒng)的方式來(lái)處理狀態(tài)轉(zhuǎn)換,相信狀態(tài)上了10多個(gè)以上的時(shí)候,每個(gè)地方都是If else判斷測(cè)試的時(shí)候,你就知道痛苦了,在處理訂單狀態(tài)時(shí)候,10多個(gè)狀態(tài)也是常有的事情,我們可以借助狀態(tài)模式來(lái)解決這個(gè)問(wèn)題,在多次項(xiàng)目過(guò)程中,使用該模式之后明顯感覺(jué)狀態(tài)處理要清晰得多,即使中間涉及到刪減或增加一些狀態(tài)?中間狀態(tài),該模式處理起來(lái)游刃有余。
? 狀態(tài)轉(zhuǎn)換,絕大多數(shù)是由于事件觸發(fā)引起的,currentStatus___event___nextStatus,即在當(dāng)前狀態(tài)下發(fā)生了一個(gè)事件促使?fàn)顟B(tài)轉(zhuǎn)移到下一個(gè)狀態(tài),設(shè)計(jì)模式中詳細(xì)進(jìn)行了闡述,這里我只給一個(gè)簡(jiǎn)單的實(shí)現(xiàn)。
public enum Status {
?? ?wait(1) {// 等待發(fā)送狀態(tài)
?? ???? @Override
?? ???? protected void initMap() {
?? ???? ??? addEventTansferMap(Event.send, sended);
?? ???? }
?? ?},
?? ?sended(2) {// 已經(jīng)發(fā)送狀態(tài)
?? ???? @Override
?? ???? protected void initMap() {
?? ???? ??? addEventTansferMap(Event.confirm, confirmed);
?? ???? }
?? ?},
?? ?confirmed(3) {// 已經(jīng)確認(rèn)狀態(tài)
?? ???? @Override
?? ???? protected void initMap() {}
?? ?};
?? ?/***************************************************************************
?? ? *
?? ? * 共有方法
?? ? *
?? ? * *******************************************************************************
?? ? */
?? ?private Status(int value) {
?? ???? this.value = value;
?? ?}
?? ?
?? ?public int getValue(){
?? ???? return this.value;
?? ?}
?? ?protected abstract void initMap();// 初始化映射事件狀態(tài)映射關(guān)系
?? ?/**
?? ? * 根據(jù)發(fā)生的事件得到下一個(gè)狀態(tài)
?? ? *
?? ? * @param e
?? ? *??????????? 事件
?? ? * @return 下一個(gè)狀態(tài),如果該事件沒(méi)有造成狀態(tài)改變,返回null
?? ? */
?? ?public final Status next(Event e) {
?? ???? init();
?? ???? return translations.get(e);
?? ?}
?? ?
?? ?/**
?? ? * 初始化事件與狀態(tài)轉(zhuǎn)換映射
?? ? */
?? ?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 發(fā)生的事件
?? ? * @param s 事件發(fā)生后轉(zhuǎn)移到的狀態(tài)
?? ? */
?? ?protected void addEventTansferMap(Event e,Status s){
?? ???? translations.put(e, s);
?? ?}
?? ?private Map<Event, Status> translations;?? ?//事件狀態(tài)映射
?? ?private boolean initialed = false;?? ?// 映射是否已經(jīng)初始化
?? ?private int value;?? ?//狀態(tài)原始值
?? ?private Object LOCK = new Object();
?? ?
?? ?
?? ?
?? ?
?? ?
?? ?
?? ?// 事件枚舉,可以單獨(dú)作為一個(gè)類
?? ?public enum Event {
?? ???? send, // 發(fā)送事件
?? ???? confirm;// 確認(rèn)事件
?? ?}
?? ?public static void main(String[] args) {
?? ???? System.out.println("下一個(gè)狀態(tài):" + wait.next(Event.send));
?? ???? System.out.println(sended.next(Event.confirm));
?? ???? System.out.println(wait.next(Event.confirm));
?? ?}
}
?由以上實(shí)現(xiàn)可以知道,新增一個(gè)狀態(tài),新增一個(gè)事件都非常簡(jiǎn)單。第一步,在Event中新增一個(gè)事件,第二步,在Status中新增一個(gè)狀態(tài) ,第三步,新增事件和狀態(tài)轉(zhuǎn)移映射(覆蓋initMap即可)。
在使用時(shí)只需要使用當(dāng)前的發(fā)生的事件作為參數(shù)調(diào)用next即可以得到下一個(gè)狀態(tài),非常簡(jiǎn)單。
總結(jié)