您的位置:首页 > 编程语言 > Java开发

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

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

什么是状态模式?

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

使用场景

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息