责任链设计模式
模式定义:
请求在一个链条上处理,链条上的受理者处理完毕之后决定是继续往后传递还是中断当前处理流程。
适用场景
适用于多节点的流程处理,每个节点完成各自负责的部分,节点之间不知道彼此的存在,比如 OA 的审批流,Java Web 开发中的 Filter 机制。
实践经验
大学食堂有个背景是这样的,食堂有补贴,菜品比较便宜,所以学校是不愿意让社会人士去学校食堂消费的,所以支付的时候会有检验
大体如下:
- 某档口只允许某类用户用户消费,比如教师档口只允许教师消费,学生档口不允许校外用户消费。
- 某个档口一天只允许某类用户消费几次,比如教师食堂一天只允许学生消费一次。
- 是否允许非清真学生消费,比如某些清真餐厅,是不允许非清真学生消费的。
面对这么多业务判断。肯定要写很多if else if else,在平时的业务开发中如果遇到很多if esle就可以使用这种。
针对这几类情况我建立了三类过滤器,分别是:
- SpecificCardUserConsumeLimitFilter:按用户类型判断是否允许消费。
- DayConsumeTimesConsumeLimitFilter:按日消费次数判断是否允许消费。
- MuslimConsumeLimitFilter:非清真用户是否允许消费。
判断逻辑是先通过 SpecificCardUserConsumeLimitFilter 判断当前用户是否可以在此档口消费。如果允许继续由 DayConsumeTimesConsumeLimitFilter 判断当天消费次数是否已用完;如果未用完继续由 MuslimConsumeLimitFilter 判断当前用户是否满足清真餐厅的就餐条件,前面三条判断,只要有一个不满足就提前返回。
public boolean canConsume(String uid,String shopId,String supplierId){
//获取用户信息,用户信息包含类型(student:学生,teacher:老师,unknown:未知用户)、名族(han:汉族,mg:蒙古族)
UserInfo userInfo = getUserInfo(uid);
//获取消费限制信息,限制信息包含是否允许非清真消费、每种类型的用户是否允许消费以及允许消费的次数
ConsumeConfigInfo consumeConfigInfo = getConsumeConfigInfo(shopId,supplierId)
// 构造消费限制过滤器链条
ConsumeLimitFilterChain filterChain = new ConsumeLimitFilterChain();
filterChain.addFilter(new SpecificCardUserConsumeLimitFilter());
filterChain.addFilter(new DayConsumeTimesConsumeLimitFilter());
filterChain.addFilter(new MuslimConsumeLimitFilter());
boolean checkResult = filterChain.doFilter(filterChain, schoolMemberInfo, consumeConfigInfo);
}
//filterChain.doFilter方法
public boolean doFilter(ConsumeLimitFilterChain filterChain,UserInfo userInfo,
ConsumeConfigInfo consumeConfigInfo ){
//迭代调用过滤器
if(index<filters.size()){
return filters.get(index++).doFilter(filterChain, userInfo, consumeConfigInfo);
}
}
//SpecificCardUserConsumeLimitFilter.doFilter方法
public boolean doFilter(ConsumeLimitFilterChain filterChain,UserInfo userInfo,
ConsumeConfigInfo consumeConfigInfo ){
//获取某一类型的消费限制,比如student允许消费,unknown不允许消费
CardConsumeConfig cardConsumeConfig = findSuitCardConfig(userInfo, consumeConfigInfo);
// 判断当前卡用户是否允许消费
if (consumeCardConfig != null) {
if ((!CAN_PAY.equals(cardConsumeConfig .getEnabledPay()))) {
return false;
}
}
//其余情况,继续往后传递
return filterChain.doFilter(filterChain, memberInfo, consumeConfig);
}
//DayConsumeTimesConsumeLimitFilter.doFilter方法
public boolean doFilter(ConsumeLimitFilterChain filterChain,UserInfo userInfo,ConsumeConfigInfo consumeConfigInfo ){
//获取某一类型的消费限制,比如student可以消费2次
CardConsumeConfig cardConsumeConfig = findSuitCardConfig(userInfo, consumeConfigInfo);
//获取当前用户今天的消费次数
int consumeCnt = getConsumeCnt(userInfo)
if(consumeCnt >= cardConsumeConfig.getDayConsumeTimesLimit()){
return false;
}
//其余情况,继续往后传递
return filterChain.doFilter(filterChain, memberInfo, consumeConfig);
}
本文转自:https://blog.csdn.net/g6U8W7p06dCO99fQ3/article/details/109019677