大多数时候我都是写一些业务代码,可能一堆CRUD就能解决问题,但是这样的工作对技术人的提升并不多,如何让自己从业务中解脱出来找到写代码的乐趣呢,我做过一些尝试,使用设计模式改善自己的业务代码就是其中的一种。
责任链设计模式
定义
请求在一个链条上处理,链条上的受理者处理完毕之后决定是继续往后传递还是中断当前处理流程。
适用场景
适用于多节点的流程处理,每个节点完成各自负责的部分,节点之间不知道彼此的存在,比如OA的审批流,java web开发中的Filter机制。举一个生活中的例子,笔者之前租房的时候遇到了所谓的黑中介,租的时候感觉自己是上帝,但是坏了东西找他修的时候就像个孙子一样,中介让我找门店客服,门店客服又让我找房东,房东又让我找她家老公,最终好说歹说才把这事了了(租房一定要找正规中介)。
实践经验
笔者目前所做的业务是校园团餐的聚合支付,业务流程很简单,1.学生打开手机付款码支付,2.食堂大妈使用机具扫付款码收款。大学食堂有个背景是这样的,食堂有补贴,菜品比较便宜,所以学校是不愿意让社会人士去学校食堂消费的,鉴于此,我们在支付之前加了一套是否允许支付的检验逻辑,大体如下:
1.某档口只允许某类用户用户消费,比如教师档口只允许教师消费,学生档口不允许校外用户消费;2.某个档口一天只允许某类用户消费几次,比如教师食堂一天只允许学生消费一次;3.是否允许非清真学生消费,比如某些清真餐厅,是不允许非清真学生消费的;
针对这几类情况我建立了三类过滤器,分别是:
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不允许消费
CardConsu