设计模式 - 一个关于规则处理的代码设计问题请教

查看:245
本文介绍了设计模式 - 一个关于规则处理的代码设计问题请教的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

业务介绍

商品可以打上特定的标签 如9.9元秒杀 特价款 5折抢购 标签有限制用券规则 如

  • 禁止用券

  • 禁止使用XX元以上的优惠券

  • 禁止使用店铺券

于是当下单展示可用优惠券列表时 需要基于商品的标签 排除相应的券

为了解耦 调用标签模块的接口 得到禁止用券的规则 如

    Map<String,String> getDisableCouponRule(int tagId);

返回结果有

  • disableAll : true (禁止用券)

  • disableCouponPriceGreatEqual : 30 (禁止使用30元以上(含)的优惠券)

  • disableCouponType : shop (禁止使用店铺券)

然后基于返回的规则 排除相应的优惠券 如


if("true".equals(ruleMap.get("disableAll"))){
    return empty_list;   
}
for (Coupon coupon : couponList){ // 遍历用户优惠券 排除不符合条件的优惠券
    if(ruleMap.get("disableCouponPriceGreatEqual") != null){
        if(coupon.getPrice() >= parseInt(ruleMap.get("disableCouponPriceGreatEqual"))){
            continue;
        }
    }
    if(ruleMap.get("disableCouponType")!=null){
        if(coupon.getType() == getTypeIntValue(ruleMap.get("disableCouponType"))){continue;}
    }
}

目前业务还算简单 就这么几种规则 万一以后要新增规则 如

  • 小于YY元的优惠券不能使用

增加一个if语句就是了

但是总觉得if语句不够优雅 不知有没什么设计模式或DSL适合这种场景?

这种场景适合使用规则引擎吗? 是不是太重了?

解决方案

最终决定采用spring el表达式来实现

  • 标签禁止用券 返回 "true"

  • 新人专享 (类目新客) 禁止使用40元以上的优惠券 couponPrice > 40

  • 特价款 5折抢购 禁止使用店铺优惠券 couponType == 2

代码示例

        String disabledCouponRule = "true"; // 禁止用券
        Coupon coupon = new Coupon(BigDecimal.valueOf(50),2); // 50元面额 店铺券
        ExpressionParser expressionParser = new SpelExpressionParser();
        Expression expression = expressionParser.parseExpression(disabledCouponRule);
        boolean result = expression.getValue(coupon, Boolean.class);
        assertTrue(result);
        
        String disabledCouponRule = "couponPrice > 40"; // 禁止使用40元以上的优惠券

        Coupon coupon = new Coupon(BigDecimal.valueOf(39),1);
        ExpressionParser expressionParser = new SpelExpressionParser();
        Expression expression = expressionParser.parseExpression(disabledCouponRule);
        boolean result = expression.getValue(coupon, Boolean.class);
        assertFalse(result); // 小于40 可用

        coupon = new Coupon(BigDecimal.valueOf(40),1);
        expression = expressionParser.parseExpression(disabledCouponRule);
        result = expression.getValue(coupon, Boolean.class);
        assertFalse(result); // 等于40 不可用

        coupon = new Coupon(BigDecimal.valueOf(41),1);
        expression = expressionParser.parseExpression(disabledCouponRule);
        result = expression.getValue(coupon, Boolean.class);
        assertTrue(result); // 大于40 不可用
        
        String disabledCouponRule = "couponType == 2"; // 禁止使用店铺优惠券 2表示店铺券

        Coupon coupon = new Coupon(BigDecimal.valueOf(30),1); // 平台券
        ExpressionParser expressionParser = new SpelExpressionParser();
        Expression expression = expressionParser.parseExpression(disabledCouponRule);
        boolean result = expression.getValue(coupon, Boolean.class);
        assertFalse(result); // 平台券 可用

        coupon = new Coupon(BigDecimal.valueOf(30),2);
        expression = expressionParser.parseExpression(disabledCouponRule);
        result = expression.getValue(coupon, Boolean.class);
        assertTrue(result); // 店铺券 不可用

参考文档
http://www.baeldung.com/sprin...

这篇关于设计模式 - 一个关于规则处理的代码设计问题请教的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆