java设计模式之责任链模式

最近业务上有这个需求:给服务顾问分配服务订单(一个服务订单就是对应的一个资源客户)时,需要层层过滤规则。具体的有如下规则:1、顾问性别规则;2、服务顾问分配数上限规则;3、收入规则;4、本地优先规则;5、顾问分配间隔规则(即一个顾问在间隔8小时内只能被分一个单子);
具体操作就是:首先查询出满足条件的所有服务顾问id,放到一个数组里面(下文统称ids),然后依次通过上述规则的过滤判断,把过滤后的ids传给下一个规则里面过滤,直到最后一个规则过滤完成,返回最终的ids;
在这里面,我想到了设计模式-责任链模式;
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于将请求的发送者和接收者解耦,并允许多个对象都有机会处理该请求。在责任链模式中,请求沿着一个由多个对象组成的链传递,直到有一个对象能够处理请求为止。
定义责任链模式的关键思想是:将处理请求的对象组织成一个链条,并将请求沿着链条传递,直到有一个对象能够处理它为止。每个处理对象都有一个指向下一个处理对象的引用,形成一个链式结构。
责任链模式的定义包括以下关键要点:
发送者与接收者解耦:责任链模式将发送者和接收者解耦,使得发送者无需知道请求将由哪个具体接收者处理,而接收者也无需知道请求的发送者是谁。
1、多个对象组成链:责任链模式由多个对象组成一条链,每个对象都有机会处理请求。这些对象被称为处理者(Handler)。
2、处理者的责任:每个处理者都有一个对下一个处理者的引用,形成了一个链条。当请求到达一个处理者时,该处理者可以选择处理请求或将其传递给下一个处理者。
3、动态的请求处理流程:责任链模式允许在运行时动态地改变请求的处理流程。可以根据实际情况来配置和调整链条中的处理者顺序。
4、责任链模式的核心思想是将请求沿着链条传递,直到有一个处理者能够处理它为止。这种模式适用于存在多个处理者处理同一类型请求的情况,而发送者无法确定哪个处理者将处理请求,或者希望动态地指定处理者的情况。
通过使用责任链模式,可以实现请求的动态处理、解耦发送者和接收者、以及提高代码的灵活性和可扩展性。

具体代码实现:
我为每个规则定义了一个对象,然后统一继承一个父对象,定义一个链式对象(AcMatchCalcHardRuleChain),把每个对象都添加到链式中(通过add方法)

    public List<String> screenDacTAgentIds(CustTagMsgVo custTag, CustBusinessBean cbb, List<String> agentIds) {

        AcMatchCalcHardRuleChain hardChain = new AcMatchCalcHardRuleChain();
        hardChain.add(acMatchAgentGenderRule).add(acMatchNumRule).add(acMatchCDRule).add(acMatchAgentLocalRule).add(acMatchTimeRule);

        return hardChain.doFilter(custTag,cbb,agentIds);

    }

链式对象的具体实现如下:

public class AcMatchCalcHardRuleChain {



    List<AcMatchCalcHardRule> filters = new ArrayList<>();

    int index = 0;

    public AcMatchCalcHardRuleChain add(AcMatchCalcHardRule filter){
        filters.add(filter);
        return this;
    }

    public List<String> doFilter(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds){


        if(index == filters.size()) {
            return agentIds;
        }
        AcMatchCalcHardRule f = filters.get(index);
        index ++;
		// 这里会调用具体的规则对象的实现方法
        List<String> info = f.doFilter(custTag,businessBean,agentIds, this);
        if(null == info){
            return null;
        }

        return info;

    }

}

如上图所示:acMatchAgentGenderRule、acMatchNumRule、acMatchCDRule、
acMatchAgentLocalRule、acMatchTimeRule 对应的是每一个规则对象,他们都继承一个
AcMatchCalcHardRule (硬性规则),然后AcMatchCalcHardRule 继承了AcMatchCalcRule 匹配计算规则(最终父规则),上图中的f.doFilter方法中的 this 就是链式对象,指向下一个处理对象的引用

我们随机看一个具体的规则对象的doFilter实现方法

    @Override
    public List<String> rule(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds) {

        List<String> thisAgentIds = new ArrayList<>(agentIds);

        if(null == custTag.getHopeAgentGender()){
            return thisAgentIds;
        }

        if(custTag.getHopeAgentGender() == 1 || custTag.getHopeAgentGender() == 2){
            thisAgentIds = agentMongoDao.findByIdAndGender(thisAgentIds,custTag.getHopeAgentGender());
        }

        return thisAgentIds;
    }
    @Override
    public List<String> doFilter(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds, AcMatchCalcHardRuleChain chain ){

        log.info("AcMatchAgentGenderRule 处理前:{}",agentIds.size());
        List<String> thisAgentIds = rule(custTag,businessBean,agentIds);
        if(EmptyUtils.isEmpty(thisAgentIds)){
            log.info("AcMatchAgentGenderRule 处理后:{}",0);
            return null;
        }
        log.info("AcMatchAgentGenderRule 处理后:{}",thisAgentIds.size());
        return chain.doFilter(custTag,businessBean,thisAgentIds);

    }

以下是一个具体的对象规则的详细代码(AcMatchAgentGenderRule 是性别规则)

@Slf4j
@Component("acMatchAgentGenderRule")
public class AcMatchAgentGenderRule implements AcMatchCalcHardRule {

    @Autowired
    private AgentMongoDao agentMongoDao;

    @Override
    public List<String> calc(CustTagMsgVo custTag, CustBusinessBean businessBean, List agentIds) {
        return rule(custTag,  businessBean, agentIds);
    }

    @Override
    public List<String> rule(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds) {

        List<String> thisAgentIds = new ArrayList<>(agentIds);

        if(null == custTag.getHopeAgentGender()){
            return thisAgentIds;
        }

        if(custTag.getHopeAgentGender() == 1 || custTag.getHopeAgentGender() == 2){
            thisAgentIds = agentMongoDao.findByIdAndGender(thisAgentIds,custTag.getHopeAgentGender());
        }

        return thisAgentIds;
    }

    @Override
    public List<String> doFilter(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String
public interface AcMatchCalcHardRule extends AcMatchCalcRule {

    AcRuleTypeEnum rule = AcRuleTypeEnum.hard;


    List<String> rule(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds);


    List<String> doFilter(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds, AcMatchCalcHardRuleChain chain );

}
public interface AcMatchCalcRule {

    List<String> calc(CustTagMsgVo custTag, CustBusinessBean businessBean, List<String> agentIds);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值