业务投放场景责任链模式
Posted java_wxid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了业务投放场景责任链模式相关的知识,希望对你有一定的参考价值。
文章目录
创建design-demo项目
项目代码:https://gitee.com/java_wxid/java_wxid/tree/master/demo/design-demo
项目结构如下(示例):
需求分析
责任链模式核心功能:允许规则实时增减和顺序调整。
如果按照传统模式开发,这里难以满足上述规则实时增减和顺序调整,其次过滤规则有可能根据产品需求灵活变动,一旦发生变动就会对业务层代码进行修改,从而可能影响之前开发好的业务逻辑。
创建UserController
代码如下(示例):
package com.example.designdemo.controller;
import com.example.designdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:
*/
@RestController
public class UserController
@Autowired
private UserService userService;
@GetMapping("/suggest")
public List<String> suggestRequirement(@RequestParam String username)
return userService.suggestRequirement(username);
创建AbstractSuggestRequirementHandler
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:
*/
public abstract class AbstractSuggestRequirementHandler
abstract void processHandler(UserInfo userInfo, List<String> suggestLists);
创建CityCheckHandler
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:用户所在城市是否满足业务投放城市
*/
public class CityCheckHandler extends AbstractSuggestRequirementHandler
@Override
public void processHandler(UserInfo userInfo, List<String> suggestLists)
//通过获取 userinfo 的 city 属性
String city = userInfo.getCity();
// 通过city 和 之前保留的 4 个 业务信息进行对比。然后筛选出剩余的 3 个 业务投放
suggestLists.remove("1");
创建NewCheckHandler
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:新用户首次购买投放指定业务
*/
public class NewCheckHandler extends AbstractSuggestRequirementHandler
@Override
public void processHandler(UserInfo userInfo, List<String> suggestLists)
//通过获取 userinfo 的 buyProducts 属性
boolean newUser = userInfo.isNewUser();
if(newUser)
suggestLists = new ArrayList<>(); // 特定的新用户奖励
创建PersonnalCheckHandler
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:用户资质是否满足业务投放资质
*/
public class PersonnalCheckHandler extends AbstractSuggestRequirementHandler
@Override
public void processHandler(UserInfo userInfo, List<String> suggestLists)
// 通过个人资质的check,我们找到了 4 个可以投放的业务。放到 suggestLists 中。
suggestLists.add("1");
suggestLists.add("2");
suggestLists.add("3");
suggestLists.add("4");
创建RecentCheckHandler
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:用户近期购买的商品是否符合投放的人群
*/
public class RecentCheckHandler extends AbstractSuggestRequirementHandler
@Override
public void processHandler(UserInfo userInfo, List<String> suggestLists)
//通过获取 userinfo 的 buyProducts 属性
List<String> buyProducts = userInfo.getBuyProducts();
// buyProducts 和 之前保留的 3 个 业务信息进行对比。然后筛选出剩余的 2 个 业务投放
suggestLists.remove("2");
创建SuggestRequirementHandlerProcess
代码如下(示例):
package com.example.designdemo.handler;
import com.example.designdemo.pojo.UserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 19:26
* @Description:
*/
@Component
public class SuggestRequirementHandlerProcess
@Value("#'$suggest.requirement.handler'.split(',')")
private List<String> handlers;
public void process(UserInfo userInfo, List<String> suggestLists)
// 如果想要实时的进行顺序的调整或者是增减。那必须要使用配置中心进行配置。比如springcloud里边自带的 git 的这种配置中心; applo 配置中心;nacos配置中心。
try
for(String handler : handlers)
AbstractSuggestRequirementHandler handle =
(AbstractSuggestRequirementHandler) Class.forName(handler).newInstance();
handle.processHandler(userInfo, suggestLists);
catch (Exception e)
创建UserInfo
代码如下(示例):
package com.example.designdemo.pojo;
import java.util.List;
public class UserInfo
private String username;
private String city;
private List<String> buyProducts;
private boolean isNewUser;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getCity()
return city;
public void setCity(String city)
this.city = city;
public List<String> getBuyProducts()
return buyProducts;
public void setBuyProducts(List<String> buyProducts)
this.buyProducts = buyProducts;
public boolean isNewUser()
return isNewUser;
public void setNewUser(boolean newUser)
isNewUser = newUser;
创建UserService
代码如下(示例):
package com.example.designdemo.service;
import java.util.List;
/**
* @Author: zhiwei Liao
* @Date: 2022/9/25 9:28
* @Description:
*/
public interface UserService
List<String> suggestRequirement(String username);
创建UserServiceImpl
代码如下(示例):
package com.example.designdemo.service.impl;
import com.example.designdemo.handler.SuggestRequirementHandlerProcess;
import com.example.designdemo.pojo.UserInfo;
import com.example.designdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl implements UserService
@Autowired
private SuggestRequirementHandlerProcess suggestRequirementHandlerProcess;
@Override
public List<String> suggestRequirement(String username)
//获取用户信息。因为用户已经登录了,那么user的信息是保存在我们的缓存里的。
UserInfo userInfo = getUserInfo(username);
List<String> results = new ArrayList<>();
//可以发现,调用方无需关心任何 handler。完全对其屏蔽的。而且是完全解耦
suggestRequirementHandlerProcess.process(userInfo, results);
return results;
//因为这部分是需要查询 缓存(如果缓存没有,需要查库)不应该写到 service层,但是为了代码书写简便
//这部分我模拟在service 层。
private UserInfo getUserInfo(String username)
return new UserInfo();
修改application.properties
代码如下(示例):
# 应用名称
spring.application.name=design-demo
# 这里比喻成配置中心 先后顺序决定投放执行的逻辑
# 这里我们先执行PersonnalCheckHandler用户资质是否满足业务投放资质,为用户添加投放业务1,2,3,4.
# 然后再执行CityCheckHandler用户所在城市是否满足业务投放城市,移除用户投放业务1.
# 接着执行RecentCheckHandler用户近期购买的商品是否符合投放的人群,移除用户投放业务2。
# 最后执行NewCheckHandler新用户首次购买投放指定业务,给业务特定业务奖励。最终给用户投放业务3,4
suggest.requirement.handler=com.example.designdemo.handler.PersonnalCheckHandler,com.example.designdemo.handler.CityCheckHandler,com.example.designdemo.handler.RecentCheckHandler,com.example.designdemo.handler.NewCheckHandler
接口调用测试是否正常工作
如下图(示例):
接口调用逻辑讲解
请求进来
如下图(示例):
以上是关于业务投放场景责任链模式的主要内容,如果未能解决你的问题,请参考以下文章