命令模式 PK 策略模式

从代码实现上,可能看起来是差不多的,都是一个接口,一堆实现类

命令模式

重要在一个行为,你将同一类不同的操作,封装成一堆命令,这些命令的意义在于说,后续可以基于这些命令执行各种复杂和高级的操作,命令模式非常适合跟工厂方法模式结合起来使用,就是使用多个工厂来制造出不同的命令类来,将命令的构造放在工厂方法中。
比如说命令在队列里面排队,这个就是很典型的这么一个例子,不同的命令给分类,放到不同的内存队列里面去排队,异步化
命令,支持撤销操作 -> 执行一个命令,撤销一个命令 -> 这个多个命令可以给一个通用的基础类,封装一些通用的基础逻辑。

策略模式

if else
if 后面跟100行代码,else if 后面跟200行, else 后又是300行代码, 慢慢就会变的很难维护

对于有相似的输入输出参数,但是中间逻辑不一样的代码

将if后面的代码,抽到一个策略类里去;else if后面的代码抽到一个策略类里去;给每个类以及类中的方法设计更加合理,清晰,面向对象的名称,让整个复杂的业务逻辑,代码结构更加的清晰,便于你未来可以读懂,利于维护这套代码。

区别:策略模式是封装,而命令模式是封装+操作行为

策略模式只是简单的进行面向对象的代码抽离,减少太长的if else
而命令模式,在封装为一个命令对象后,还可以对这个命令对象执行各种复杂的操作。
比如某个步骤增加growth_value,那么反向操作就是减少;某个步骤是插入明细数据到数据库,反向操作就是删除这条明细数据。
也就是说,我们如果将这个更新的操作封装成命令的概念,后续就可以对这个命令做各种副复杂的高级的操作,排队,撤销。其实就是说,命令模式真正的真谛,就在于说将某个操作封装成一个命令的概念,在后面可以对这些命令做一些复杂的操作,排队、撤销。

需求背景

在一个有会员体系的应用中,一个用户在应用内的很多的行为,都会导致他的会员积分和等级的变化。
把各种会影响到用户会员积分的行为,都封装为一个相应的命令。

如果说用户支付了一个订单,那么我们会对这个操作,执行一个命令,这个命令里面,可能会去累加成长值,升级会员等级,累加会员积分;但是,如果之后这个商品被退货了,那么此时就需要对这个命令执行一个撤销操作,这个命令就会基于之前的执行操作的一些结果或者是中间状态的一些记录,将当时执行的那个命令给他撤销掉

假设影响会员积分的有如下三种命令:
(1)用户每天第一次登录,这个是一个命令,但是是没有撤销操作的
(2)支付订单,是一个命令,是有撤销操作的,如果下一次对这个订单进行了退货,就要将这个命令执行他的撤销操作
(3)发表评论,是一个命令,是有撤销操作的,如果下一次这个评论刚开始通过了审核,上了,但是后面又被人投诉了,被删除了,此时就要执行这个命令的撤销操作

给这些命令搞一个抽象的基类,里面封装一些命令相关的通用基础逻辑。

实现

既然每种情况都有执行和撤销操作,那么封装一个接口,每个会员命令都有执行execute和撤销undo两个方法(同理,如果还有删除,冻结等操作也是)

/**
 * 会员信息更新组件接口
 * @author 
 *
 */
public interface MembershipUpdater<T, K> {  

	/**
	 * 执行会员信息更新的操作
	 * @param userAccountId 用户账号id 
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	K execute(Long userAccountId, T parameter) throws Exception;
	
	/**
	 * 撤销会员信息更新的操作
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	K undo(Long userAccountId, T parameter) throws Exception;
	
}

因为不同的命令实现,有一些共性:
都会计算更新积分,然后存储结果、
都会计算更新会员等级,然后存储结果、
都会创建会员等级更新明细,并储存。

因此,把这些共性的流程,抽取一个基类AbstractMembershipUpdater 在基类的execute和undo里面去组织共性的流程
而把一些有逻辑差异的细节,定义模板方法在子类中去实现
更新会员积分 protected abstract Map<String, Object> updateMemberPoint
更新会员等级 protected abstract Map<String, Object> updateMemberLevel
获取更新理由 protected abstract String getMemberLevelUpdateReason

/**
 * 会员信息更新组件的抽象基类
 * @author 
 *
 */
public abstract class AbstractMembershipUpdater<T, K> implements MembershipUpdater<T, K> { 

	/**
	 * 会员等级明细管理DAO组件
	 */
	protected MemberLevelDetailDAO memberLevelDetailDAO;
	/**
	 * 会员积分明细管理DAO组件
	 */
	protected MemberPointDetailDAO memberPointDetailDAO;
	
	public AbstractMembershipUpdater(MemberLevelDetailDAO memberLevelDetailDAO,
			MemberPointDetailDAO memberPointDetailDAO) {
		this.memberLevelDetailDAO = memberLevelDetailDAO;
		this.memberPointDetailDAO = memberPointDetailDAO;
	}

	/**
	 * 执行会员信息更新的操作
	 * @param userAccountId 用户账号id 
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	public K execute(Long userAccountId, T parameter) throws Exception {
		Map<String, Object> updateMemberLevelResult = updateMemberLevel(userAccountId, parameter); 
		Map<String, Object> updateMemberPointResult = updateMemberPoint(userAccountId, parameter); 
		saveMemberLevelDetail(userAccountId, parameter, updateMemberLevelResult); 
		saveMemberPointDetail(userAccountId, parameter, updateMemberPointResult); 
		return finishExecute(userAccountId, parameter);
	}
	
	/**
	 * 撤销会员信息更新的操作
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	public K undo(Long userAccountId, T parameter) throws Exception {
		Map<String, Object> undoMemberLevelResult = undoUpdatedMemberLevel(userAccountId, parameter); 
		Map<String, Object> undoMemberPointResult = undoUpdatedMemberPoint(userAccountId, parameter); 
		saveUndoMemberLevelDetail(userAccountId, parameter, undoMemberLevelResult); 
		saveUndoMemberPointDetail(userAccountId, parameter, undoMemberPointResult); 
		return finishUndo(userAccountId, parameter);
	}
	
	/**
	 * 更新会员等级
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	protected abstract Map<String, Object> updateMemberLevel(
			Long userAccountId, T parameter) throws Exception;
	
	/**
	 * 更新会员积分
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @throws Exception
	 */
	protected abstract Map<String, Object> updateMemberPoint(
			Long userAccountId, T parameter) throws Exception;
	
	/**
	 * 获取会员等级更新原因
	 * @param userAccountId
	 * @param parameter
	 * @param updateMemberLevelResult
	 * @return
	 * @throws Exception
	 */
	protected abstract String getMemberLevelUpdateReason(Long userAccountId,
			T parameter, Map<String, Object> updateMemberLevelResult) throws Exception;
	
	/**
	 * 新增一条会员等级更新明细
	 * @param userAccountId 用户账号id 
	 * @param parameter 参数
	 * @param updateMemberLevelResult 更新会员等级结果
	 * @throws Exception
	 */
	private void saveMemberLevelDetail(Long userAccountId, 
			T parameter, Map<String, Object> updateMemberLevelResult) throws Exception {
		MemberLevelDetailDO memberLevelDetail = createMemberLevelDetail(
				userAccountId, updateMemberLevelResult);
		memberLevelDetail.setUpdateReason(getMemberLevelUpdateReason(
				userAccountId, parameter, updateMemberLevelResult));
		memberLevelDetailDAO.save(memberLevelDetail); 
	}
	
	/**
	 * 创建会员等级更新明细
	 * @param userAccountId
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private MemberLevelDetailDO createMemberLevelDetail(Long userAccountId,
			Map<String, Object> updateResult) throws Exception {
		MemberLevelDetailDO memberLevelDetail = new MemberLevelDetailDO();
		
		memberLevelDetail.setUserAccountId(userAccountId); 
		memberLevelDetail.setOldGrowthValue(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberLevelResult.OLD_GROWTH_VALUE))));   
		memberLevelDetail.setUpdatedGrowthValue(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberLevelResult.UPDATED_GROWTH_VALUE))));   
		memberLevelDetail.setNewGrowthValue(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberLevelResult.NEW_GROWTH_VALUE))));   
		memberLevelDetail.setOldMemberLevel(Integer.valueOf(String.valueOf(
				updateResult.get(UpdateMemberLevelResult.OLD_MEMBER_LEVEL))));   
		memberLevelDetail.setNewMemberLevel(Integer.valueOf(String.valueOf(
				updateResult.get(UpdateMemberLevelResult.NEW_MEMBER_LEVEL))));
		
		return memberLevelDetail;
	}
	
	/**
	 * 获取会员积分更新原因
	 * @param userAccountId
	 * @param parameter
	 * @param updateMemberLevelResult
	 * @return
	 * @throws Exception
	 */
	protected abstract String getMemberPointUpdateReason(Long userAccountId,
			T parameter, Map<String, Object> updateMemberPointResult) throws Exception;
	
	/**
	 * 新增一条会员积分更新明细
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @param updateMemberPointResult 更新会员积分结果
	 * @throws Exception
	 */
	private void saveMemberPointDetail(Long userAccountId,
			T parameter, Map<String, Object> updateMemberPointResult) throws Exception {
		MemberPointDetailDO memberPointDetail = createMemberPointDetail(
				userAccountId, updateMemberPointResult);
		memberPointDetail.setUpdateReason(getMemberPointUpdateReason(
				userAccountId, parameter, updateMemberPointResult));
		memberPointDetailDAO.save(memberPointDetail); 
	}
	
	/**
	 * 创建会员积分明细
	 * @return 会员积分明细
	 * @throws Exception
	 */
	private MemberPointDetailDO createMemberPointDetail(Long userAccountId,
			Map<String, Object> updateResult) throws Exception {
		MemberPointDetailDO memberPointDetail = new MemberPointDetailDO();
		
		memberPointDetail.setUserAccountId(userAccountId); 
		
		memberPointDetail.setOldMemberPoint(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberPointResult.OLD_MEMBER_POINT))));   
		memberPointDetail.setUpdatedMemberPoint(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberPointResult.UPDATED_MEMBER_POINT))));   
		memberPointDetail.setNewMemberPoint(Long.valueOf(String.valueOf(
				updateResult.get(UpdateMemberPointResult.NEW_MEMBER_POINT)))); 
		
		return memberPointDetail;
	}
	
	/**
	 * 完成执行本次会员信息更新操作
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	protected abstract K finishExecute(Long userAccountId, 
			T parameter) throws Exception;
	
	/**
	 * 撤销更新的会员等级
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 撤销结果
	 * @throws Exception
	 */
	protected abstract Map<String, Object> undoUpdatedMemberLevel(Long userAccountId, 
			T parameter) throws Exception;
	
	/**
	 * 撤销更新的会员积分
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 撤销结果
	 * @throws Exception
	 */
	protected abstract Map<String, Object> undoUpdatedMemberPoint(Long userAccountId,
			T parameter) throws Exception;
	
	/**
	 * 获取撤销会员等级更新原因
	 * @param userAccountId
	 * @param parameter
	 * @param updateMemberLevelResult
	 * @return
	 * @throws Exception
	 */
	protected abstract String getUndoMemberLevelUpdateReason(Long userAccountId,
			T parameter, Map<String, Object> undoMemberLevelResult) throws Exception;
	
	/**
	 * 获取撤销会员积分更新原因
	 * @param userAccountId
	 * @param parameter
	 * @param updateMemberLevelResult
	 * @return
	 * @throws Exception
	 */
	protected abstract String getUndoMemberPointUpdateReason(Long userAccountId,
			T parameter, Map<String, Object> undoMemberPointResult) throws Exception;
	
	/**
	 * 新增一条会员等级撤销操作更新明细
	 * @param userAccountId 用户账号id 
	 * @param parameter 参数
	 * @param undoMemberLevelResult 撤销会员等级结果
	 * @throws Exception
	 */
	private void saveUndoMemberLevelDetail(Long userAccountId, 
			T parameter, Map<String, Object> undoMemberLevelResult) throws Exception {
		MemberLevelDetailDO memberLevelDetail = createMemberLevelDetail(
				userAccountId, undoMemberLevelResult);
		memberLevelDetail.setUpdateReason(getUndoMemberLevelUpdateReason(
				userAccountId, parameter, undoMemberLevelResult));
		memberLevelDetailDAO.save(memberLevelDetail); 
	}
	
	/**
	 * 新增一条会员积分撤销操作更新明细
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @param undoMemberPointResult 撤销会员积分结果
	 * @throws Exception
	 */
	private void saveUndoMemberPointDetail(Long userAccountId,
			T parameter, Map<String, Object> undoMemberPointResult) throws Exception {
		MemberPointDetailDO memberPointDetail = createMemberPointDetail(
				userAccountId, undoMemberPointResult);
		memberPointDetail.setUpdateReason(getUndoMemberPointUpdateReason(
				userAccountId, parameter, undoMemberPointResult)); 
		memberPointDetailDAO.save(memberPointDetail); 
	}
	
	/**
	 * 完成撤销会员信息更新操作
	 * @param userAccountId 用户账号id
	 * @param parameter 参数
	 * @return 返回值
	 * @throws Exception
	 */
	protected abstract K finishUndo(Long userAccountId, 
			T parameter) throws Exception;
	
}


对于可能造成用户积分加减,会员等级加减的三个事件,封装成三个事件的命令实现类:

每日第一次登陆:FirstLoginMembershipUpdater
支付订单命令(可撤销):PayOrderMembershipUpdater
发表评论(可撤销):PublishCommentMembershipUpdater


/**
 * 支付订单的会员信息更新组件
 * @author 
 *
 */
@Component
public class PayOrderMembershipUpdater extends AbstractMembershipUpdater<Object, Boolean> {

	/**
	 * 支付订单的会员成长值累加值比例
	 */
	private static final Double PAY_ORDER_GROWTH_VALUE_UPDATE_RATE = 0.1;
	/**
	 * 支付订单的会员积分累加值比例
	 */
	private static final Double PAY_ORDER_MEMBER_POINT_UPDATE_RATE = 0.1;
	
	/**
	 * 会员等级管理DAO组件
	 */
	@Autowired
	private MemberLevelDAO memberLevelDAO;
	/**
	 * 会员积分管理DAO组件
	 */
	@Autowired
	private MemberPointDAO memberPointDAO;
	
	@Autowired
	public PayOrderMembershipUpdater(
			MemberLevelDetailDAO memberLevelDetailDAO,
			MemberPointDetailDAO memberPointDetailDAO) {
		super(memberLevelDetailDAO, memberPointDetailDAO);
	}
	
	/**
	 * 更新会员等级
	 */
	@Override
	protected Map<String, Object> updateMemberLevel(Long userAccountId, 
			Object parameter) throws Exception {
		Long totalOrderAmount = (Long) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberLevelDO memberLevel = memberLevelDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberLevelResult.OLD_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.OLD_MEMBER_LEVEL, memberLevel.getLevel());
		
		memberLevel.setGrowthValue(memberLevel.getGrowthValue() 
				+ Math.round(totalOrderAmount * PAY_ORDER_GROWTH_VALUE_UPDATE_RATE));   
		memberLevel.setLevel(MemberLevel.get(memberLevel.getGrowthValue()));  
		memberLevelDAO.update(memberLevel); 
		
		result.put(UpdateMemberLevelResult.UPDATED_GROWTH_VALUE, 
				Math.round(totalOrderAmount * PAY_ORDER_GROWTH_VALUE_UPDATE_RATE));
		result.put(UpdateMemberLevelResult.NEW_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.NEW_MEMBER_LEVEL, memberLevel.getLevel());
		
		return result;
	}
	
	/**
	 * 更新会员积分
	 */
	@Override
	protected Map<String, Object> updateMemberPoint(Long userAccountId, 
			Object parameter) throws Exception {
		Long totalOrderAmount = (Long) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberPointDO memberPoint = memberPointDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberPointResult.OLD_MEMBER_POINT, memberPoint.getPoint());
		
		memberPoint.setPoint(memberPoint.getPoint() 
				+ Math.round(totalOrderAmount * PAY_ORDER_MEMBER_POINT_UPDATE_RATE)); 
		memberPointDAO.update(memberPoint); 
		
		result.put(UpdateMemberPointResult.UPDATED_MEMBER_POINT, 
				Math.round(totalOrderAmount * PAY_ORDER_MEMBER_POINT_UPDATE_RATE));
		result.put(UpdateMemberPointResult.NEW_MEMBER_POINT, memberPoint.getPoint());
		
		return result;
	}
	
	/**
	 * 获取会员等级更新原因
	 */
	@Override
	protected String getMemberLevelUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> updateMemberLevelResult) throws Exception {
		return "支付了订单,订单金额为:" + parameter;
	}
	
	/**
	 * 获取会员积分更新原因
	 */
	@Override
	protected String getMemberPointUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> updateMemberPointResult) throws Exception {
		return "支付了订单,订单金额为:" + parameter;
	}
	
	/**
	 * 完成更新会员信息
	 */
	@Override
	protected Boolean finishExecute(Long userAccountId, Object parameter) throws Exception {
		return true;
	}
	
	/**
	 * 撤销更新会员等级
	 */
	@Override
	protected Map<String, Object> undoUpdatedMemberLevel(Long userAccountId, 
			Object parameter) throws Exception {
		Long totalOrderAmount = (Long) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberLevelDO memberLevel = memberLevelDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberLevelResult.OLD_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.OLD_MEMBER_LEVEL, memberLevel.getLevel());
		
		memberLevel.setGrowthValue(memberLevel.getGrowthValue() 
				- Math.round(totalOrderAmount * PAY_ORDER_GROWTH_VALUE_UPDATE_RATE));   
		memberLevel.setLevel(MemberLevel.get(memberLevel.getGrowthValue()));  
		memberLevelDAO.update(memberLevel); 
		
		result.put(UpdateMemberLevelResult.UPDATED_GROWTH_VALUE, 
				- Math.round(totalOrderAmount * PAY_ORDER_GROWTH_VALUE_UPDATE_RATE));
		result.put(UpdateMemberLevelResult.NEW_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.NEW_MEMBER_LEVEL, memberLevel.getLevel());
		
		return result;
	}
	
	/**
	 * 撤销更新会员积分
	 */
	@Override
	protected Map<String, Object> undoUpdatedMemberPoint(Long userAccountId, 
			Object parameter) throws Exception {
		Long totalOrderAmount = (Long) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberPointDO memberPoint = memberPointDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberPointResult.OLD_MEMBER_POINT, memberPoint.getPoint());
		
		memberPoint.setPoint(memberPoint.getPoint() 
				- Math.round(totalOrderAmount * PAY_ORDER_MEMBER_POINT_UPDATE_RATE)); 
		memberPointDAO.update(memberPoint); 
		
		result.put(UpdateMemberPointResult.UPDATED_MEMBER_POINT, 
				- Math.round(totalOrderAmount * PAY_ORDER_MEMBER_POINT_UPDATE_RATE));
		result.put(UpdateMemberPointResult.NEW_MEMBER_POINT, memberPoint.getPoint());
		
		return result;
	}
	
	/**
	 * 获取撤销会员等级的原因
	 */
	@Override
	protected String getUndoMemberLevelUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> undoMemberLevelResult) throws Exception {
		return "对订单进行了退货,订单金额为:" + parameter;
	}
	
	/**
	 * 获取撤销会员积分的原因
	 */
	@Override
	protected String getUndoMemberPointUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> undoMemberPointResult) throws Exception {
		return "对订单进行了退货,订单金额为:" + parameter;
	}
	
	/**
	 * 完成撤销操作
	 */
	@Override
	protected Boolean finishUndo(Long userAccountId, Object parameter) throws Exception {
		return true;
	}

}


/**
 * 发表评论的会员信息更新组件
 * @author
 *
 */
@Component
public class PublishCommentMembershipUpdater extends AbstractMembershipUpdater<Object, Boolean> {

	/**
	 * 发表评论成长值
	 */
	private static final Long PUBLISH_COMMENT_GROWTH_VALUE_UPDATE = 10L;
	/**
	 * 晒单的成长值
	 */
	private static final Long SHOW_PICTURES_GROWTH_VALUE_UPDATE = 10L;
	/**
	 * 发表评论会员积分
	 */
	private static final Long PUBLISH_COMMENT_MEMBER_POINT_UPDATE = 10L;
	/**
	 * 晒单的会员积分
	 */
	private static final Long SHOW_PICTURES_MEMBER_POINT_UPDATE = 10L;
	
	/**
	 * 会员等级管理DAO组件
	 */
	@Autowired
	private MemberLevelDAO memberLevelDAO;
	/**
	 * 会员积分管理DAO组件
	 */
	@Autowired
	private MemberPointDAO memberPointDAO;
	
	@Autowired
	public PublishCommentMembershipUpdater(
			MemberLevelDetailDAO memberLevelDetailDAO,
			MemberPointDetailDAO memberPointDetailDAO) {
		super(memberLevelDetailDAO, memberPointDetailDAO);
	}
	
	/**
	 * 更新会员等级
	 */
	@Override
	protected Map<String, Object> updateMemberLevel(Long userAccountId, 
			Object parameter) throws Exception {
		Boolean showPictures = (Boolean) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberLevelDO memberLevel = memberLevelDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberLevelResult.OLD_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.OLD_MEMBER_LEVEL, memberLevel.getLevel());
		
		memberLevel.setGrowthValue(memberLevel.getGrowthValue() + PUBLISH_COMMENT_GROWTH_VALUE_UPDATE 
				+ (showPictures ? SHOW_PICTURES_GROWTH_VALUE_UPDATE : 0));
		memberLevel.setLevel(MemberLevel.get(memberLevel.getGrowthValue()));  
		memberLevelDAO.update(memberLevel); 
		
		result.put(UpdateMemberLevelResult.UPDATED_GROWTH_VALUE, PUBLISH_COMMENT_GROWTH_VALUE_UPDATE 
				+ (showPictures ? SHOW_PICTURES_GROWTH_VALUE_UPDATE : 0));
		result.put(UpdateMemberLevelResult.NEW_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.NEW_MEMBER_LEVEL, memberLevel.getLevel());
		
		return result;
	}
	
	/**
	 * 更新会员积分
	 */
	@Override
	protected Map<String, Object> updateMemberPoint(Long userAccountId, 
			Object parameter) throws Exception {
		Boolean showPictures = (Boolean) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberPointDO memberPoint = memberPointDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberPointResult.OLD_MEMBER_POINT, memberPoint.getPoint());
		
		memberPoint.setPoint(memberPoint.getPoint() + PUBLISH_COMMENT_MEMBER_POINT_UPDATE 
				+ (showPictures ? SHOW_PICTURES_MEMBER_POINT_UPDATE : 0)); 
		memberPointDAO.update(memberPoint); 
		
		result.put(UpdateMemberPointResult.UPDATED_MEMBER_POINT, PUBLISH_COMMENT_MEMBER_POINT_UPDATE 
				+ (showPictures ? SHOW_PICTURES_MEMBER_POINT_UPDATE : 0));
		result.put(UpdateMemberPointResult.NEW_MEMBER_POINT, memberPoint.getPoint());
		
		return result;
	}
	
	/**
	 * 获取会员等级更新原因
	 */
	@Override
	protected String getMemberLevelUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> updateMemberLevelResult) throws Exception {
		return "发表了一条评论" + ((Boolean)parameter ? ",同时晒了单" : ""); 
	}
	
	/**
	 * 获取会员积分更新原因
	 */
	@Override
	protected String getMemberPointUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> updateMemberPointResult) throws Exception {
		return "发表了一条评论" + ((Boolean)parameter ? ",同时晒了单" : ""); 
	}
	
	/**
	 * 完成更新会员信息
	 */
	@Override
	protected Boolean finishExecute(Long userAccountId, Object parameter) throws Exception {
		return true;
	}
	
	/**
	 * 撤销更新会员等级
	 */
	@Override
	protected Map<String, Object> undoUpdatedMemberLevel(Long userAccountId, 
			Object parameter) throws Exception {
		Boolean showPictures = (Boolean) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberLevelDO memberLevel = memberLevelDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberLevelResult.OLD_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.OLD_MEMBER_LEVEL, memberLevel.getLevel());
		
		memberLevel.setGrowthValue(memberLevel.getGrowthValue() - PUBLISH_COMMENT_GROWTH_VALUE_UPDATE 
				- (showPictures ? SHOW_PICTURES_GROWTH_VALUE_UPDATE : 0));
		memberLevel.setLevel(MemberLevel.get(memberLevel.getGrowthValue()));  
		memberLevelDAO.update(memberLevel); 
		
		result.put(UpdateMemberLevelResult.UPDATED_GROWTH_VALUE, -(PUBLISH_COMMENT_GROWTH_VALUE_UPDATE 
				+ (showPictures ? SHOW_PICTURES_GROWTH_VALUE_UPDATE : 0))); 
		result.put(UpdateMemberLevelResult.NEW_GROWTH_VALUE, memberLevel.getGrowthValue());
		result.put(UpdateMemberLevelResult.NEW_MEMBER_LEVEL, memberLevel.getLevel());
		
		return result;
	}
	
	/**
	 * 撤销更新会员积分
	 */
	@Override
	protected Map<String, Object> undoUpdatedMemberPoint(Long userAccountId, 
			Object parameter) throws Exception {
		Boolean showPictures = (Boolean) parameter;
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		MemberPointDO memberPoint = memberPointDAO.getByUserAccountId(userAccountId);
		
		result.put(UpdateMemberPointResult.OLD_MEMBER_POINT, memberPoint.getPoint());
		
		memberPoint.setPoint(memberPoint.getPoint() - PUBLISH_COMMENT_MEMBER_POINT_UPDATE 
				- (showPictures ? SHOW_PICTURES_MEMBER_POINT_UPDATE : 0)); 
		memberPointDAO.update(memberPoint); 
		
		result.put(UpdateMemberPointResult.UPDATED_MEMBER_POINT, -(PUBLISH_COMMENT_MEMBER_POINT_UPDATE 
				+ (showPictures ? SHOW_PICTURES_MEMBER_POINT_UPDATE : 0)));
		result.put(UpdateMemberPointResult.NEW_MEMBER_POINT, memberPoint.getPoint());
		
		return result;
	}
	
	/**
	 * 获取撤销会员等级的原因
	 */
	@Override
	protected String getUndoMemberLevelUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> undoMemberLevelResult) throws Exception {
		return "发表的一条评论被删除了" + ((Boolean)parameter ? ",同时这个评论是晒单的" : ""); 
	}
	
	/**
	 * 获取撤销会员积分的原因
	 */
	@Override
	protected String getUndoMemberPointUpdateReason(Long userAccountId, Object parameter,
			Map<String, Object> undoMemberPointResult) throws Exception {
		return "发表的一条评论被删除了" + ((Boolean)parameter ? ",同时这个评论是晒单的" : ""); 
	}
	
	/**
	 * 完成撤销操作
	 */
	@Override
	protected Boolean finishUndo(Long userAccountId, Object parameter) throws Exception {
		return true;
	}

}

在上层对封装好的命令使用:

例如:会员中心接口MembershipService对外接受2个事件的方法:
支付订单事件:需要执行支付命令增加积分

	/**
	 * 通知会员中心,“支付订单”事件发生了
	 * @param userAccountId 用户账号id
	 * @param totalOrderAmount 订单总金额
	 * @return 处理结果
	 */
	public Boolean informPayOrderEvent(Long userAccountId, Long totalOrderAmount) {
		try {
			payOrderMembershipUpdater.execute(userAccountId, totalOrderAmount);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}

退货事件:需要撤销支付命令减少积分

	/**
	 * 通知会员中心,“完成退货”事件发生了
	 * @param userAccountId 用户账号id
	 * @param totalOrderAmount 订单总金额
	 * @return 处理结果
	 */
	public Boolean informFinishReturnGoodsEvent(Long userAccountId, Long totalOrderAmount) {
		try {
			payOrderMembershipUpdater.undo(userAccountId, totalOrderAmount);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}


/**
 * 会员中心对外接口service组件
 * @author 
 *
 */
@Service
public class MembershipServiceImpl implements MembershipService {
	
	private static final Logger logger = LoggerFactory.getLogger(
			MembershipServiceImpl.class);
	
	/**
	 * 用户账号DAO组件
	 */
	@Autowired
	private UserAccountDAO userAccountDAO;
	/**
	 * 每天第一次登录会员信息更新组件
	 */
	@Autowired
	private FirstLoginMembershipUpdater firstLoginMembershipUpdater;
	/**
	 * 支付订单会员信息更新组件
	 */
	@Autowired
	private PayOrderMembershipUpdater payOrderMembershipUpdater;
	/**
	 * 发表评论会员信息更新组件
	 */
	@Autowired
	private PublishCommentMembershipUpdater publishCommentMembershipUpdater;
	
	/**
	 * 通知会员中心,“用户今日第一次登录”事件发生了
	 * @param userAccountId 用户账号ID
	 * @return 处理结果
	 */
	public Boolean informFirstLoginDailyEvent(Long userAccountId) {
		try {
			firstLoginMembershipUpdater.execute(userAccountId, null);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}
	
	/**
	 * 通知会员中心,“支付订单”事件发生了
	 * @param userAccountId 用户账号id
	 * @param totalOrderAmount 订单总金额
	 * @return 处理结果
	 */
	public Boolean informPayOrderEvent(Long userAccountId, Long totalOrderAmount) {
		try {
			payOrderMembershipUpdater.execute(userAccountId, totalOrderAmount);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}
	
	/**
	 * 通知会员中心,“完成退货”事件发生了
	 * @param userAccountId 用户账号id
	 * @param totalOrderAmount 订单总金额
	 * @return 处理结果
	 */
	public Boolean informFinishReturnGoodsEvent(Long userAccountId, Long totalOrderAmount) {
		try {
			payOrderMembershipUpdater.undo(userAccountId, totalOrderAmount);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}
	
	/**
	 * 通知会员中心,“发表评论”事件发生了
	 * @param userAccountId 用户账号id
	 * @param showPictures 是否晒图
	 * @return 处理结果
	 */
	public Boolean informPublishCommentEvent(Long userAccountId, Boolean showPictures) {
		try {
			publishCommentMembershipUpdater.execute(userAccountId, showPictures);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}
	
	/**
	 * 通知会员中心,“删除评论”事件发生了
	 * @param userAccountId 用户账号id
	 * @param showPictures 是否晒图
	 * @return 处理结果
	 */
	public Boolean informRemoveCommentEvent(Long userAccountId, Boolean showPictures) {
		try {
			publishCommentMembershipUpdater.undo(userAccountId, showPictures);
			return true;
		} catch (Exception e) {
			logger.error("error", e); 
			return false;
		}
	}
	
	/**
	 * 查询所有的用户账户
	 * @return
	 */
	public List<UserAccountDTO> listAllUserAccounts() {
		try {
			return ObjectUtils.convertList(userAccountDAO.listAll(), UserAccountDTO.class);
		} catch (Exception e) { 
			logger.error("error", e); 
			return new ArrayList<UserAccountDTO>(); 
		}
	}

}