• 【设计模式】【第二章】【业务投放场景】【责任链模式】


    创建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 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 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 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 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 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 suggestLists) {
            //通过获取 userinfo 的 buyProducts 属性
            List 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 handlers;
    
        public void process(UserInfo userInfo, List 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 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 getBuyProducts() {
            return buyProducts;
        }
    
        public void setBuyProducts(List 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 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 suggestRequirement(String username) {
            //获取用户信息。因为用户已经登录了,那么user的信息是保存在我们的缓存里的。
            UserInfo userInfo = getUserInfo(username);
            List 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
    

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

    如下图(示例):
    在这里插入图片描述


    接口调用逻辑讲解

    请求进来
    如下图(示例):
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 相关阅读:
    【云原生】portainer管理多个独立docker服务器
    arm day1(9.14)arm相关概念,RISC和CISC区别,数据类型约定,arm-v7架构和arm-v8架构,arm处理器工作模式
    如何查看dnSpy反编译异步代码
    [2020 新春红包题]3(libc2.29 tcache tashing unlink )
    CAS:1604673-42-8 (Biotin-PEG4-Mal, 生物素PEG-MAL)
    Java中的<<、>>、>>>运算符
    2022系统架构师考试---冲刺文档整理
    java计算机毕业设计售楼系统(附源码、数据库)
    Linux操作系统的内存使用方法详细解析
    beego开发博客系统学习(二)
  • 原文地址:https://blog.csdn.net/java_wxid/article/details/127040438