`
zorufa876
  • 浏览: 81035 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

《设计模式之禅》--在项目中的应用(1)

 
阅读更多

最近找了一些设计模式方面的书来读,看来看去,还是《设计模式之禅》这本书比较合我的胃口,可能作者写的比较幽默吧,而且举得例子也比较有趣,对于我这种跳脱的人比较有吸引了,恰好,在最近的项目中也用到了合适的设计模式:

1:状态模式,最近在做一个项目,是关于交易流程方面的,交易流程大家应该都知道,无非是涉及到各个状态之间的装换,而我这个项目却比较特殊,因为原先已经有一个交易系统了,而这个交易系统只支持我们这边的项目的80%的功能,比如我们这边需要13个状态来表示交易过程中的各个流程,但是交易系统那边只支持10个状态,那怎么办呢,最后,我们只能想到用A+B的模式来做,就是我们这边也弄一份数据,而这份数据冗余了交易系统的数据的同时,也增加了我们这边独特的交易状态,那么问题就来了,如何保证数据的一致性呢,我们打算用公司的消息重试工具去做,很简单,首先公司的交易系统一旦修改数据,他那么就会发一个消息到我们这里,然后我们再同步的修改状态,如果修改失败了,就重试,而在交易系统发消息到我们这里的时候,我其实是知道要从哪个状态到哪个状态的,那么在这里,自然而然就想到了状态模式,根据这个消息发送过来的初始状态和目标状态,来决定接下来走哪个流程。这里,我觉得还是画个流程图比较合适(请查看附件)

 

如图所示,这里的状态模式涉及到三层:

第一层--State接口,里面定义了要到哪个状态的方法

第二层--StaeBase,这一层实现了接口的方法

第三次--StateOne,StateTwo,StateThree,用三个对象定义三种交易状态,这三个子类并不会实现接口的所有方法,只会实现需要实现的方法,因为很简单,并不是从任何一个状态都会跳转到另一个状态的。

 

定义了四个个方法,前三个方法里面实现的就是到各个状态需要做的事情。

最后一个toThisState方法比较特别,这里实现的就是任何一个状态要想跳转到本状态需要调用哪个方法,比如StateOne这个类

里面的方法实现就是:

 public boolean toThisState(State state,Object obj) {
        return state.toStateOne(obj);
 }
 

 

 

此外,为了控制交易状态的流程,我还设计了一个StateContext的类,当前文说的消息发送过来的时候,我已经知道了这个时候的初始状态和目标状态,那么我就会调用setOriginalState,setTargetState这两个方法,来设置初始状态和目标状态,然后再调用execute来执行状态之间的流转,那么这个execute方法又做了什么事情呢,举个例子,比如我现在要从状态1跳转到状态2,那么初始状态设置好了,是StateOne,目标状态是StateTwo,那么在execute里面,我就会调用StateTwo.toThisState(State stateOne)这个方法。这样的话,运用状态模式,整个方法就通了,且没有一处用到if  else,程序的扩展性也非常好。

 

 

下面是StateContex.java这个类的代码:

package com.taobao.smtm.biz.state;

import java.util.Map;
import com.alibaba.common.logging.Logger;
import com.alibaba.common.logging.LoggerFactory;


public class StateContext{
   
   protected Logger log = LoggerFactory.getLogger(this.getClass());
   private State originalState;
   private State targetState;
   Map<String,State> stateMap;//这里的stateMap是通过spring注入,根据规定好的数字或字符串得到相应的状态
   

   public boolean setOriginalState(String originalStateKey) {
	   this.originalState = stateMap.get(originalStateKey);  
	   if(this.originalState==null){
		   log.error("state change error, the originalStateKey is error ,the originalStateKey="+originalStateKey);
		   return false;
	   }
	   return true;
   }
   
   public boolean setTargetState(String targetStateKey) {
	   this.targetState = stateMap.get(targetStateKey);
	   if(this.targetState==null){
		   log.error("state change error, the targetStateKey is error ,the targetStateKey="+targetStateKey);
		   return false;
	   }
	   return true;
   }

	public boolean execute(Object obj) {
		if (obj == null) {
			log.error("state change error , the obj is null");
			return false;
		}
		try {
			// 执行状态的流转
			return this.targetState.fromState(this.originalState, obj);
		} catch (Exception e) {
			log.error("state change error ", e);
			return false;
		}
	}

	public void setStateMap(Map<String, State> stateMap) {
		this.stateMap = stateMap;
	}

}
 

 

 

  • 大小: 99.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics