从头捋一遍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);
}
相关文章
|
2月前
|
Java
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
本文介绍了如何使用IDEA(IntelliJ IDEA)创建一个新的Java项目,并运行一个简单的Java程序输出"Hello Word"。文章详细展示了创建项目的步骤,包括选择JDK版本、设置项目名称和路径、创建包和类,以及编写和运行代码。最后,还展示了如何通过IDEA的运行功能来执行程序并查看输出结果。
161 4
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
|
1月前
|
关系型数据库 MySQL Java
【MySQL+java+jpa】MySQL数据返回项目的感悟
【MySQL+java+jpa】MySQL数据返回项目的感悟
44 1
|
1月前
|
编解码 Oracle Java
java9到java17的新特性学习--github新项目
本文宣布了一个名为"JavaLearnNote"的新GitHub项目,该项目旨在帮助Java开发者深入理解和掌握从Java 9到Java 17的每个版本的关键新特性,并通过实战演示、社区支持和持续更新来促进学习。
79 3
|
3月前
|
IDE Java 开发工具
Java系统中的错误码设计问题之为Java项目中的错误消息提供国际化支持如何解决
Java系统中的错误码设计问题之为Java项目中的错误消息提供国际化支持如何解决
51 0
|
8天前
|
Java Android开发
Eclipse 创建 Java 项目
Eclipse 创建 Java 项目
26 4
|
14天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
28 3
|
16天前
|
前端开发 Java 数据库
如何实现一个项目,小白做项目-java
本教程涵盖了从数据库到AJAX的多个知识点,并详细介绍了项目实现过程,包括静态页面分析、数据库创建、项目结构搭建、JSP转换及各层代码编写。最后,通过通用分页和优化Servlet来提升代码质量。
38 1
|
1月前
|
JavaScript 前端开发 Java
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
355 1
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
|
23天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
1月前
|
缓存 Java Maven
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
如何解决Java项目中因JDK版本不匹配导致的编译错误,包括修改`pom.xml`文件、调整项目结构、设置Maven和JDK版本,以及清理缓存和重启IDEA。
50 1
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本