从头捋一遍Java项目中的五大设计原则,就不信你学不会!(中)

简介: 从头捋一遍Java项目中的五大设计原则,就不信你学不会!(中)

接着可以将注册逻辑拆解为注册处理器和使用注册处理器的service模块:


/**
 * @Author linhao
 * @Date created in 7:56 上午 2021/9/3
 */
public interface IRegisterService {
    /**
     * 用户注册之后处理函数
     *
     * @param registerInputParam 用户注册之后的传入参数
     */
    void postProcessorAfterRegister(RegisterInputParam registerInputParam);
}


注册处理器内部才是真正的核心部分:


/**
 * @Author linhao
 * @Date created in 8:10 上午 2021/9/3
 */
public abstract class AbstractRegisterHandler {
    /**
     * 获取注册渠道ID
     *
     * @return
     */
    public abstract int getSource();
    /**
     * 注册之后的核心通知模块程序
     *
     * @param registerInputParam
     * @return
     */
    public abstract boolean doPostProcessorAfterRegister(RegisterInputParam registerInputParam);
}


具体的实现交给了各个Handler组件:


公众号注册渠道的后置处理器


/**
 * @Author linhao
 * @Date created in 8:16 上午 2021/9/3
 */
public class GZHRegisterHandler  extends AbstractRegisterHandler {
    @Override
    public int getSource() {
        return RegisterConstants.RegisterEnum.GZH_CHANNEL.getCode();
    }
    @Override
    public boolean doPostProcessorAfterRegister(RegisterInputParam registerInputParam) {
        System.out.println("公众号处理逻辑");
        return true;
    }
}


app注册渠道的后置处理器


/**
 * @Author linhao
 * @Date created in 8:16 上午 2021/9/3
 */
public class AppRegisterHandler extends AbstractRegisterHandler {
    @Override
    public int getSource() {
        return RegisterConstants.RegisterEnum.APP_CHANNEL.getCode();
    }
    @Override
    public boolean doPostProcessorAfterRegister(RegisterInputParam registerInputParam) {
        System.out.println("app处理逻辑");
        return true;
    }
}


不同的注册渠道号通过一个枚举来进行管理:


public class RegisterConstants {
    public enum RegisterEnum{
        GZH_CHANNEL(0,"公众号渠道"),
        APP_CHANNEL(1,"app渠道");
        RegisterEnum(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }
        int code;
        String desc;
        public int getCode() {
            return code;
        }
    }
}


接下来,对于注册的后置处理服务接口进行实现:


/**
 * @Author linhao
 * @Date created in 7:48 上午 2021/9/3
 */
public class RegisterServiceImpl implements IRegisterService {
    private static List<AbstractRegisterHandler> registerHandlerList = new ArrayList<>();
    static {
        registerHandlerList.add(new GZHRegisterHandler());
        registerHandlerList.add(new AppRegisterHandler());
    }
    @Override
    public void postProcessorAfterRegister(RegisterInputParam registerInputParam) {
        for (AbstractRegisterHandler abstractRegisterHandler : registerHandlerList) {
            if(abstractRegisterHandler.getSource()==registerInputParam.getSource()){
                abstractRegisterHandler.doPostProcessorAfterRegister(registerInputParam);
                return;
            }
        }
        throw new RuntimeException("未知注册渠道号");
    }
}


最后通过简单的一段测试程序:


public class Test {
    public static void main(String[] args) {
        RegisterInputParam registerInputParam = new RegisterInputParam();
        registerInputParam.setUserId(10012);
        registerInputParam.setSource(0);
        IRegisterService registerService = new RegisterServiceImpl();
        registerService.postProcessorAfterRegister(registerInputParam);
        RegisterInputParam registerInputParam2 = new RegisterInputParam();
        registerInputParam2.setUserId(10013);
        registerInputParam2.setSource(1);
        registerService.postProcessorAfterRegister(registerInputParam2);
        System.out.println("=======");
    }
}


这样的设计和起初最先前的设计相比有几处不同的完善点:


新增不同注册渠道的时候,只需要关心注册渠道的source参数。


同时对于后续业务的拓展,新增不同的注册渠道的时候,RegisterServiceImpl只需要添加新编写的注册处理器类即可。


image.png


再回过头来看,这样的一段代码设计是否满足了开放封闭原则呢?


每次新增不同的注册类型处理逻辑之后,程序中都只需要新增一种Handler处理器,这种处理器对于原先的业务代码并没有过多的修改,从整体设计的角度来看,并没有对原有的代码结构造成影响,而且灵活度相比之前有所提高。这也正好对应了,对扩展开放,对修改关闭。


如果你对设计模式有一定了解的话,可能还会发现大多数常用的设计模式都在遵守这一项原则,例如模版模式,策略模式,责任链模式等等。


里氏替换原则


我认为,里氏替换原则更多是体现在了父子类继承方面,强调的是子类在继承了父类对象的时候不应该破坏这个父类对象的设计初衷。


举个例子来说:


我们定义了一个提款的服务:


/**
 * @Author linhao
 * @Date created in 11:21 上午 2021/9/4
 */
public interface DrawMoneyService {
    /**
     * 提款函数
     *
     * @param drawMoneyInputParam
     */
    void drawMoney(DrawMoneyInputParam drawMoneyInputParam);
}


对应的是一个抽象实现父类:


/**
 * @Author linhao
 * @Date created in 11:25 上午 2021/9/4
 */
public abstract class AbstractDrawMoneyServiceImpl implements DrawMoneyService{
    /**
     * 设计初衷,需要对提现金额进行参数校验
     * 
     * @param drawMoneyInputParam
     */
    @Override
    public abstract void drawMoney(DrawMoneyInputParam drawMoneyInputParam);
}
相关文章
|
1月前
|
Java 关系型数据库
JAVA面向对象设计原则
JAVA面向对象设计原则
12 1
|
1月前
|
Java 应用服务中间件 开发工具
苍穹外卖》电商实战项目(java)知识点整理(上)
苍穹外卖》电商实战项目(java)知识点整理(上)
191 3
|
2月前
|
Java Maven
java修改当前项目的maven仓库地址为国内
修改当前项目的maven仓库地址为国内
|
1月前
|
SQL Java 应用服务中间件
Java项目防止SQL注入的四种方案
Java项目防止SQL注入的四种方案
39 0
|
2月前
|
JavaScript Java 应用服务中间件
centos部署vue项目(java,tomcat环境的搭建)
centos部署vue项目(java,tomcat环境的搭建)
42 0
|
30天前
|
人工智能 监控 算法
java智慧城管源码 AI视频智能分析 可直接上项目
Java智慧城管源码实现AI视频智能分析,适用于直接部署项目。系统运用互联网、大数据、云计算和AI提升城市管理水平,采用“一级监督、二级指挥、四级联动”模式。功能涵盖AI智能检测(如占道广告、垃圾处理等)、执法办案、视频分析、统计分析及队伍管理等多个模块,利用深度学习优化城市管理自动化和智能化,提供决策支持。
219 4
java智慧城管源码 AI视频智能分析 可直接上项目
|
2月前
|
监控 IDE Java
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
40 0
|
14天前
|
监控 数据可视化 安全
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
环境实时数据、动态监测报警,实时监控施工环境状态,有针对性地预防施工过程中的环境污染问题,打造文明生态施工,创造绿色的生态环境。
12 0
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
|
16天前
|
SQL Java Go
java项目超市购物管理系统
java项目超市购物管理系统
|
16天前
|
Java
java项目日历表
java项目日历表