管道模式
管道模式
创建管道
package com.mall.order.biz.factory;/**
* Created on 2019/8/2.
*/
import com.mall.order.biz.TransOutboundInvoker;
/**
*
*/
public interface TransPipelineFactory<T> {
TransOutboundInvoker build(T obj);
}
抽象工厂具体实现
package com.mall.order.biz.factory;/**
* Created by cskaoyan on 2019/8/2.
*/
import com.mall.commons.result.AbstractRequest;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.convert.CreateOrderConvert;
import com.mall.order.biz.handler.DefaultTransPipeline;
import com.mall.order.biz.handler.TransPipeline;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.convert.TransConvert;
/**
* cskaoyan
*/
public abstract class AbstranctTransPipelineFactory <T extends AbstractRequest> implements TransPipelineFactory<T>{
@Override
public final TransOutboundInvoker build(T obj) {
//创建转换器 CreateOrderConvert new CreateOrderConvert(),实现了这个方法
//为了把request转换成对象,转换器和产品没关系
// TransConvert convert = new CreateOrderConvert();
TransConvert convert = createConvert();
//创建上下文 创建一个流水线的产品 本质 new CreateOrderContext();
//TransHandlerContext context = new CreateOrderContext();
//为什么这么写呢,因为他是一个接口,接口下面可以有很多实现类
//Context要看具体是谁的context
TransHandlerContext context = createContext();
//上朔,多态转型
//AbsTransHandlerContext实现了TransHandlerContext
AbsTransHandlerContext absCtx = (AbsTransHandlerContext) context;
//set转换器
//为什么有这一步
absCtx.setConvert(convert);
//上下文转换 obj = request,把obj变成context
//这个是把这里的context传过去,相当于new好了,让他里面有东西
convert.convertRequest2Ctx(obj, context);
//创建管道,这一步才是创建管道,之前的都是前置操作
TransPipeline pipeline = createPipeline(context);
//build管道
//放入具体的handle
doBuild(pipeline);
//返回
return pipeline;
}
protected abstract TransHandlerContext createContext();
protected abstract void doBuild(TransPipeline pipeline);
protected TransPipeline createPipeline(TransHandlerContext context) {
return new DefaultTransPipeline(context);
}
protected abstract TransConvert createConvert();
}
具体工厂,这里是订单工厂
package com.mall.order.biz.factory;
import com.mall.order.biz.handler.*;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.biz.convert.CreateOrderConvert;
import com.mall.order.biz.convert.TransConvert;
import com.mall.order.dto.CreateOrderRequest;
import com.mall.order.biz.handler.ClearCartItemHandler;
import com.mall.order.biz.handler.SendMessageHandler;
import com.mall.order.biz.handler.SubStockHandler;
import com.mall.order.biz.handler.ValidateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
*
* 构建订单处理链
*/
@Slf4j
@Service
public class OrderProcessPipelineFactory extends AbstranctTransPipelineFactory<CreateOrderRequest> {
@Autowired
private InitOrderHandler initOrderHandler;
@Autowired
private ValidateHandler validateHandler;
@Autowired
private LogisticalHandler logisticalHandler;
@Autowired
private ClearCartItemHandler clearCartItemHandler;
@Autowired
private SubStockHandler subStockHandler;
@Autowired
private SendMessageHandler sendMessageHandler;
@Override
protected TransHandlerContext createContext() {
CreateOrderContext createOrderContext=new CreateOrderContext();
return createOrderContext;
}
@Override
protected void doBuild(TransPipeline pipeline) {
pipeline.addLast(validateHandler);
pipeline.addLast(subStockHandler);
pipeline.addLast(initOrderHandler);
pipeline.addLast(logisticalHandler);
pipeline.addLast(clearCartItemHandler);
pipeline.addLast(sendMessageHandler);
}
@Override
protected TransConvert createConvert() { //构建转换器
return new CreateOrderConvert();
}
}
转换器
转换器,注意括号里面,很有可能是不同的转换器,是抽象的
package com.mall.order.biz.convert;
import com.mall.commons.result.AbstractRequest;
import com.mall.commons.result.AbstractResponse;
import com.mall.order.biz.context.TransHandlerContext;
/**
* cskaoyan
*/
public interface TransConvert {
/**
* 请求转上下文
*
* @param req
* @return
*/
TransHandlerContext convertRequest2Ctx(AbstractRequest req, TransHandlerContext context);
/**
* 上下文转应答
*
* @param ctx
* @return
*/
AbstractResponse convertCtx2Respond(TransHandlerContext ctx);
}
订单
package com.mall.order.biz.convert;/**
*/
import com.mall.commons.result.AbstractRequest;
import com.mall.commons.result.AbstractResponse;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.dto.CreateOrderRequest;
import com.mall.order.dto.CreateOrderResponse;
/**
* cskaoyan
*/
public class CreateOrderConvert implements TransConvert{
// 把我们的request转化为 context
@Override
public TransHandlerContext convertRequest2Ctx(AbstractRequest req, TransHandlerContext context) {
CreateOrderRequest createOrderRequest=(CreateOrderRequest)req;
CreateOrderContext createOrderContext=(CreateOrderContext) context;
createOrderContext.setAddressId(createOrderRequest.getAddressId());
createOrderContext.setCartProductDtoList(createOrderRequest.getCartProductDtoList());
createOrderContext.setOrderTotal(createOrderRequest.getOrderTotal());
createOrderContext.setStreetName(createOrderRequest.getStreetName());
createOrderContext.setTel(createOrderRequest.getTel());
createOrderContext.setUserId(createOrderRequest.getUserId());
createOrderContext.setUserName(createOrderRequest.getUserName());
createOrderContext.setUniqueKey(createOrderRequest.getUniqueKey());
return createOrderContext;
}
// 把我们经过管道模式处理的结果转化为response
@Override
public AbstractResponse convertCtx2Respond(TransHandlerContext ctx) {
CreateOrderContext createOrderContext=(CreateOrderContext) ctx;
CreateOrderResponse createOrderResponse=new CreateOrderResponse();
createOrderResponse.setOrderId(createOrderContext.getOrderId());
createOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
createOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
return createOrderResponse;
}
}
Context
有抽象是因为
抽象可以整合东西
package com.mall.order.biz.context;/**
*/
/**
* 交易上下文
*/
public interface TransHandlerContext {
}
抽象Context共有的
package com.mall.order.biz.context;
import com.mall.order.biz.convert.TransConvert;
import lombok.Data;
/**
* cskaoyan
* 交易相关的抽象
*/
@Data
public abstract class AbsTransHandlerContext implements TransHandlerContext {
private String orderId;
private TransConvert convert = null;
}
这里其实相当于是一个类
接收到request,需要把东西放在这个类里面
package com.mall.order.biz.context;/**
*/
import com.mall.order.dto.CartProductDto;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* cskaoyan
*/
@Data
public class CreateOrderContext extends AbsTransHandlerContext{
private Long userId;
private Long addressId;
private String tel;
private String userName;
private String streetName;
private BigDecimal orderTotal;
List<CartProductDto> cartProductDtoList;
private List<Long> buyProductIds; // 生成订单商品的ID list
private String buyerNickName; // 购买用户的昵称
private String uniqueKey; //业务唯一id
}
管道结点
管道结点是Handle
有handle,有next,有执行
package com.mall.order.biz.handler;
import com.mall.order.biz.callback.TransCallback;
import com.mall.order.biz.context.TransHandlerContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Data
public class TransHandlerNode {
private TransHandler handler;
private TransHandlerNode next = null;
public void exec(TransHandlerContext context) {
AbstractTransHandler transHandler = (AbstractTransHandler) handler;
boolean success = handler.handle(context);
//回调函数
execCallbacks(transHandler.getTransCallback(), context, null);
if (next != null) {
if (success) {
if (transHandler.isAsync()) {
//TODO 如果为true,则采用异步线程去执行任务
}
next.exec(context);
}
}
}
private void execCallbacks(TransCallback callback, TransHandlerContext context, Throwable ex) {
try {
if (ex == null&&callback!=null) {
callback.onDone(context);
}
} catch (Exception e) {
log.warn("Pipeline回调处理异常.", e);
//TODO 异常处理
}
}
}
创建管道
有开始,有关闭
package com.mall.order.biz;
import com.mall.order.biz.context.TransHandlerContext;
/**
* cskaoyan
*/
public interface TransOutboundInvoker {
/**
* 启动流程.<br/>
*
*/
void start();
/**
* 终止流程.<br/>
*
*/
void shutdown();
/**
* 用于获取返回值<br/>
*
* @return
*/
<T extends TransHandlerContext> T getContext();
}
package com.mall.order.biz.handler;/**
* Created on 2019/8/2.
*/
import com.mall.order.biz.TransOutboundInvoker;
/**
*
*/
public interface TransPipeline extends TransOutboundInvoker {
/**
*
* @param handlers
*/
void addFirst(TransHandler... handlers);
/**
*
* @param handlers
*/
void addLast(TransHandler ... handlers);
}
具体实现
package com.mall.order.biz.handler;/**
* Created on 2019/8/2.
*/
import com.mall.order.biz.context.TransHandlerContext;
import lombok.extern.slf4j.Slf4j;
/**
*
*/
@Slf4j
public class DefaultTransPipeline implements TransPipeline{
private TransHandlerNode tail;
private TransHandlerNode head = new TransHandlerNode();
private TransHandlerContext context = null;
public DefaultTransPipeline(TransHandlerContext context) {
setContext(context);
tail = head;
}
@Override
public void addFirst(TransHandler... handlers) {
TransHandlerNode pre = head.getNext();
for (TransHandler handler : handlers) {
if(handler == null) {
continue;
}
TransHandlerNode node = new TransHandlerNode();
node.setHandler(handler);
node.setNext(pre);
pre = node;
}
head.setNext(pre);
}
@Override
public void addLast(TransHandler... handlers) {
TransHandlerNode next = tail;
for (TransHandler handler : handlers) {
if(handler == null) {
continue;
}
TransHandlerNode node = new TransHandlerNode();
node.setHandler(handler);
next.setNext(node);
next = node;
}
tail = next;
}
@Override
public void start() {
try {
head.getNext().exec(getContext());
} catch (Exception ex) {
log.error("pipeline系统运行异常.", ex);
throw ex;
}
}
@Override
public void shutdown() {
;
}
@Override
public <T extends TransHandlerContext> T getContext() {
return (T)context;
}
public void setContext(TransHandlerContext context) {
this.context = context;
}
}
Handle接口
package com.mall.order.biz.handler;
import com.mall.order.biz.context.TransHandlerContext;
/**
*
*/
public interface TransHandler {
/**
* 是否采用异步方式执行
* @return
*/
boolean isAsync();
/**
* 执行交易具体业务<br/>
*
* @param context
* @return true则继续执行下一个Handler,否则结束Handler Chain的执行直接返回<br/>
*/
boolean handle(TransHandlerContext context);
}
Handle具体实现,这里面是具体的方法
package com.mall.order.biz.handler;
import com.mall.commons.tool.exception.BizException;
import com.mall.order.biz.context.CreateOrderContext;
import com.mall.order.biz.context.TransHandlerContext;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.user.IMemberService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dto.QueryMemberRequest;
import com.mall.user.dto.QueryMemberResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
*/
@Slf4j
@Component
public class ValidateHandler extends AbstractTransHandler {
@Reference(check = false)
private IMemberService memberService;
/**
* 验证用户合法性
* @return
*/
@Override
public boolean isAsync() {
return false;
}
@Override
public boolean handle(TransHandlerContext context) {
return true;
}
}