管道模式

管道模式

创建管道
image

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();
    }
}

转换器

转换器,注意括号里面,很有可能是不同的转换器,是抽象的
image
image


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

image
有抽象是因为
抽象可以整合东西

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 异常处理
        }
    }
}

创建管道

有开始,有关闭
image

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();
}

image

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;
    }
}

posted @ 2023-01-20 16:58  拿受用  阅读(61)  评论(0编辑  收藏  举报