第十节:基于责任链模式做限购商品的前置判断实操

一. 前言

1. 什么是责任链模式?

  构建一条处理链,使多个对象可以处理同一个请求,直到该请求被处理为止

 

2. 场景

 (1) 审批场景:不同天数的假期需要不同级别的领导审批。(如多级审批流程:组长→部门经理→总经理)

 (2) Asp.Net Core中间件管道:HTTP 请求需要经过多步处理(如认证、授权、缓存、路由等),每个中间件独立处理并决定是否传递给下一个

 (3) 日志场景:不同级别 / 类型的日志需要不同的处理器(如输出到控制台、文件、数据库),按优先级处理

 

3. 好处

  责任链模式通过解耦各校验步骤,使系统更适应变化,同时避免了在控制器中写冗长的if-else校验逻辑

 

4. 本次实操内容

  基于责任链模式实现限购商品下单的多级校验,依次完成 参数合法性→用户权限→商品数量(限购 + 库存)→订单金额 校验, 任何一步失败则终止流程。

 

二. 实操

1. 构建抽象类 LimitOrderHandler

   在该类中通过SetNext方法设置下一个处理者,然后声明抽象类Validate,用来处理请求

/// <summary>
/// 定义校验抽象校验类
/// </summary>
public abstract class LimitOrderHandler
{

    protected LimitOrderHandler nextHandler;   //下一个处理者

    /// <summary>
    /// 设置下一个处理者
    /// </summary>
    /// <param name="next"></param>
    public void SetNext(LimitOrderHandler next) => nextHandler = next;

    //处理请求(返回校验结果:是否通过+错误信息)
    public abstract Task<(bool isValid, string errorMsg)> Validate(OrderParam param);

}

 

2. 构建多个具体的处理者

 比如 ParamValidationHandler,实现抽象类LimitOrderHandler

 显式实现方法Validate,在里面处理具体业务,同时判断如果有一个处理者,则转向下个处理者

 


/// <summary>
/// 1. 参数合法性校验处理者
/// </summary>
public class ParamValidationHandler : LimitOrderHandler
{
    public override async Task<(bool isValid, string errorMsg)> Validate(OrderParam param)
    {
        if (param == null) { return (false, "参数为空"); }

        if (param.quantity <= 0) { return (false, "购买数量必须大约0"); }

        if (param.price <= 0) { return (false, "商品单价必须大约0"); }

        if (string.IsNullOrEmpty(param.goodsId)) { return (false, "商品id不能为空"); }

        //校验流程走完,如果有下一个处理者,则传递给下一个
        if (nextHandler != null)
        {
            return await nextHandler.Validate(param);
        }

        return (true, string.Empty);
    }
}

/// <summary>
/// 2. 用户权限校验
/// </summary>
public class UserPermissionHandle : LimitOrderHandler
{
    public override async Task<(bool isValid, string errorMsg)> Validate(OrderParam param)
    {
        //校验是否登录--模拟
        if (string.IsNullOrEmpty(param.userId)) { return (false, "用户没有登录"); }

        //校验是否是会员(限购商品仅仅会员可以购买)--模拟
        bool isVip = param.userId != null;     //正常应该DB校验
        if (!isVip) { return (false, "非VIP用户"); }


        //校验流程走完,如果有下一个处理者,则传递给下一个
        if (nextHandler != null)
        {
            return await nextHandler.Validate(param);
        }
        return (true, string.Empty);
    }
}

/// <summary>
/// 3. 商品数量校验
/// </summary>
public class QuantityLimitHandle : LimitOrderHandler
{
    public override async Task<(bool isValid, string errorMsg)> Validate(OrderParam param)
    {
        //1. 限购规则,每人最多买5件
        if (param.quantity > 5)
        {
            return (false, "限购最多买5件");
        }
        //2. 校验库存是否充足
        int stock = 100;   //DB查询
        if (param.quantity>stock)
        {
            return (false, "库存不足");
        }

        //校验流程走完,如果有下一个处理者,则传递给下一个
        if (nextHandler != null)
        {
            return await nextHandler.Validate(param);
        }
        return (true, string.Empty);
    }
}
/// <summary>
/// 4. 订单金额校验
/// </summary>
public class AmountLimitHandler : LimitOrderHandler
{
    private const decimal MinAmount = 10;    // 最低下单金额
    private const decimal MaxAmount = 5000; // 单笔最大金额(限购商品上限
    public override async Task<(bool isValid, string errorMsg)> Validate(OrderParam param)
    {
        var totalAmount = param.quantity * param.price;

        if (totalAmount < MinAmount)
            return (false, $"订单金额不能低于{MinAmount}元");

        if (totalAmount > MaxAmount)
            return (false, $"限购商品单笔金额不能超过{MaxAmount}元");


        //校验流程走完,如果有下一个处理者,则传递给下一个
        if (nextHandler != null)
        {
            return await nextHandler.Validate(param);
        }
        return (true, string.Empty);
    }
}

 

3. 初始化多个处理者

 在控制器的构造函数中实例化多个处理者,并通过setNext方法设置前后顺序 

public class Demo10Controller : Controller
{
    private readonly LimitOrderHandler validationChain;

    /// <summary>
    /// 构造函数中构建责任链
    /// </summary>
    public Demo10Controller()
    {
        //1. 创建处理者实例
        var paramValidationHandler = new ParamValidationHandler();
        var userPermissionHandle = new UserPermissionHandle();
        var quantityLimitHandle = new QuantityLimitHandle();
        var amountLimitHandler = new AmountLimitHandler();

        //2. 构建责任链
        paramValidationHandler.SetNext(userPermissionHandle);
        userPermissionHandle.SetNext(quantityLimitHandle);
        quantityLimitHandle.SetNext(amountLimitHandler);

        //抽象类用子类实现
        validationChain = paramValidationHandler;
    }
}

 

4.action中调用

 使用第一个handler进行处理校验即可,会自动转向各个链条

public class Demo10Controller : Controller
{
    private readonly LimitOrderHandler validationChain;

    /// <summary>
    /// 下单接口
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<IActionResult> PutOrder(OrderParam param)
    {
        //执行责任链校验
        var (isValid, errorMsg) = await validationChain.Validate(param);
        if (!isValid) {
            return Json(new { status = "error", msg = errorMsg });
        }
        return Json(new { status = "ok", msg = "下单成功" });
    }



}

 

 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2025-08-20 20:54  Yaopengfei  阅读(8)  评论(1)    收藏  举报