java设计模式(十一)--状态模式

        早之前就研究过老大开发的订单框架,一直想把它的最核心部分用到的设计模式放到最后面来写,作为本系列博客的收官之作。这段时间决定把部门框架的演进之路作为一个系列的博客写出来,而新框架最核心的部分就是订单,在我们的金融系统里面,所有的业务请求,都被视为一笔订单。而订单的核心代码,其实就是一个状态机的实现,下面就让我以我们部门的订单状态机为例子,阐述下我对设计模式中状态模式的理解,仅供大家交流学习。

什么是状态模式?

       状态模式是指对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类,实际是转换到了另一个实现

使用场景

       1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为;

       2. 一个操作中含有庞大的分支结构,并且这些分支决定于对象的装填。

类图(以当前我们的订单框架状态机为例):



订单状态迁移路线如下:


代码结构:



在订单初始化后(将orderState初始化为init状态),进入状态机的循环,每个循环的过程不断通过状态执行器工厂OrderStateHandlerFactory获取到状态的执行器,从而去执行该执行器的execute方法,对应的状态机的循环的代码如下:

package order;

import logic.LogicRunner;
import logic.LogicType;
import orderStateHandler.OrderStateHandler;
import orderStateHandler.OrderStateHandlerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bo.OrderContext;
import businessService.BusinessService;
import businessService.Impl.AbstractBusinessServiceImpl;

/*
 * 个人业务总入口
 */
public abstract class AbstractOrderService extends AbstractBusinessServiceImpl {
	OrderContext orderContext;

	@Override
	public void doIt(BusinessService businessService) {
		try {
			this.initOrderState();
			boolean IsInterrupt = false;
			
			while(IsInterrupt)
			{
				OrderStateHandler orderStateHandler = OrderStateHandlerFactory
						.getOrderStateHandler(businessService.getOrderContext()
								.getOrder().getOrderState().toString());

				IsInterrupt = orderStateHandler.execute(orderContext, businessService);
			}
		} catch (Exception e) 
		{
			// TODO: handle exception
		} 
		finally 
		{
			// finally
		}
	}

	private void initOrderState() {

		// 初始化bean容器
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"Beans.xml");
		orderContext.setContext(context);

		// 初始化上下文
		orderContext.getOrder().setOrderState(OrderState.INIT);

		// 执行初始化logic
		LogicRunner.ChainExecutor(orderContext.getChainId(), LogicType.INIT);
	}

}

订单执行器的获取工厂实现:

package orderStateHandler;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class OrderStateHandlerFactory 
{
	public static OrderStateHandler getOrderStateHandler(String preBeanString) throws Exception 
	{
		// bean 名字的拼装,拼装规则:前置Bean名字+ServiceConvertor
		String HandlerBeanName = preBeanString + "OrderStateProcessor";

		ApplicationContext context = new ClassPathXmlApplicationContext(
				"Beans.xml");

		// 根据Bean名字,通过spring的IoC去获取实现并返回
		OrderStateHandler orderStateHandler = (OrderStateHandler) context
				.getBean(HandlerBeanName);

		// 取到哑实现,抛异常处理
		if (null == orderStateHandler) {
			throw new Exception();
		}

		return orderStateHandler;
	}

}

在获取到订单执行器后,接下来就是各个订单执行器之间跳转,以及何时从各个执行器跳转中退出的问题了,为了强制各个状态的执行器都能设置下一个状态的跳转(避免因为程序的实现忘记设置下一个跳转状态,会导致死循环的问题),同时把一些公共的处理都放到父类实现,从而避免代码重复率的问题,这里把模板方法设计模式给使用上了,写一个抽象类AbstractOrderStateHandler,把业务的公共处理都放到这里来,下个状态的设置写成一个抽象方法,这样每个状态去继承该抽象类的时候,就强制实现该抽象方法了:

package orderStateHandler;

import bo.OrderContext;
import businessService.BusinessService;

public abstract class AbstractOrderStateHandler implements OrderStateHandler
{
	// 状态执行器
	@Override
	public boolean execute(OrderContext orderContext,BusinessService businessService)
	{
		System.out.println("entering the handleOrderState:");
		
		try {
			// 各个状态的处理
			this.handle(businessService, orderContext);
			
			// 设置下个跳转节点
			this.setNextState(businessService);
			
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return orderContext.isInterruptFlow();
	}

	public abstract void handle(BusinessService businessService,OrderContext orderContext);
	public abstract void setNextState(BusinessService businessService);
}

各个状态的执行器我就不每个都贴出来了,这里只贴一个Init状态的执行器:

package orderStateHandler;

import order.OrderState;

import bo.OrderContext;
import businessService.BusinessService;

public class InitOrderStateProcessor extends AbstractOrderStateHandler
{

	@Override
	public void handle(BusinessService businessService,
			OrderContext orderContext) 
	{
		// TODO Auto-generated method stub
		System.out.println("Entering the CompleteOrderStateProcessor handle");
		
		businessService.preInit();
		
		createOrder(orderContext);
		
		InitialContext(orderContext);
		
		orderContext.setInterruptFlow(false);
	}

	@Override
	public void setNextState(BusinessService businessService) 
	{
		if(!businessService.getOrderContext().isInterruptFlow())
		{
			businessService.getOrderContext().getOrder().setOrderState(OrderState.PROCESS);
		}
	}
	
	private void createOrder(OrderContext orderContext)
	{
		System.out.println("Creating order:");
		
	}

	private void InitialContext(OrderContext orderContext)
	{
		System.out.println("Initing orderContext:");
	}
}

bean文件配置:

<?xml version="1.0" encoding="UTF-8"?>
 
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
 		<bean id="InitOrderStateProcessor" 
			class="orderStateHandler.InitOrderStateProcessor">
 		</bean>
 	
    </beans>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值