业务投放场景责任链模式

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

接口调用测试是否正常工作

如下图(示例):


接口调用逻辑讲解

请求进来
如下图(示例):

以上是关于业务投放场景责任链模式的主要内容,如果未能解决你的问题,请参考以下文章

平台积分红包投放场景责任链模式

责任链模式在业务场景中应用

设计模式之策略模式与责任链模式详解和应用

(十五)责任链模式-代码实现

java23种设计模式之十:责任链模式

责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用