首页 > 编程语言 >java spring项目中使用设计模式和函数式编程的思想去除业务逻辑中的if else判断

java spring项目中使用设计模式和函数式编程的思想去除业务逻辑中的if else判断

时间:2022-10-30 14:55:40浏览次数:59  
标签:return String spring getBean private integer java 设计模式 public

如果你开发项目时对项目之后的发展很清晰但仍陷入了为什么要用设计模式替换if else 的疑问时就说明你项目的体量不需要用设计模式
答案只在问题提出之后有意义

策略和状态模式

网上写的比我好

工厂+简易享元模式+枚举用法

首先定义一个枚举存储业务信息

import lombok.Getter;

/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/
@Getter
public enum ParamEnum {
    ONE("one", "oneService"),
    TWO("two", "twoService");

    private final String type;

    private final String className;

    ParamEnum(String type, String className) {
        this.type = type;
        this.className = className;
    }

    public static ParamEnum getEnum(String type) throws Exception {
        for (ParamEnum value : ParamEnum.values()) {
            if (value.getType().equals(type)) {
                return value;
            }
        }
        throw new Exception("参数错误");

    }


}

定义业务接口

/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/

public interface DemoService {

    String getString(String s, Integer integer);


    //这个方法也可以去掉,然后每个实现都要加上别名
    DemoService getBean();
}

实现接口


/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/
@Service
public class DemoOneServiceImpl implements DemoService {

    @Override
    public String getString(String s, Integer integer) {
        return s + integer;
    }

    @Override
    @Bean("DemoOneServiceImpl")
    public DemoService getBean() {
        return this;
    }
}
/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/
@Service
public class DemoTwoServiceImpl implements DemoService {
    @Override
    public String getString(String s, Integer integer) {
        return integer + s;
    }

    @Override
    @Bean("DemoTwoServiceImpl")
    public DemoService getBean() {
        return this;
    }
}

创建工具类 网上有现成的可用


/**
 * spring bean 工具类
 * date: 2022-10-30
 * 这个类其实不用自己写 网上好多  比如hutool
 *
 * @author xuhb
 **/
@Component
public class SpringBeanUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringBeanUtil.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    public static <T> T getBean(Class<T> requiredType) {
        return applicationContext.getBean(requiredType);
    }

    public static <T> T getBean(String name, Class<T> requiredType) {
        return applicationContext.getBean(name, requiredType);
    }

}

创建工厂 装填服务


/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/
@Component
public class DemoServiceFactory {
    private final Map<ParamEnum,DemoService> map=new HashMap<>(16);

    @PostConstruct
    void initMap(){
        for (ParamEnum value : ParamEnum.values()) {
            map.put(value,SpringBeanUtil.getBean(value.getClassName(),DemoService.class));
        }
    }

   public DemoService getService(String type) throws Exception {
       ParamEnum paramEnum = ParamEnum.getEnum(type);
       return map.get(paramEnum);
   }
}

使用

@SpringBootTest
class DemoServiceTest {

    @Resource
    private DemoServiceFactory factory;

    @Test
    void getString() throws Exception {
        DemoService one = factory.getService("one");
        String s = one.getString("s", 23);
    }
}

函数式接口用法

对上面用法的简化
首先创建一个函数接口明确入参出参

@FunctionalInterface
public interface ParamFunction<T, U, R> {


    /**
     * 两个传参一个返回的执行 带异常抛出
     *
     * @param t 第一传参
     * @param u 第二传参
     * @return R 返回值
     * @throws Exception 方法异常
     */
    R apply(T t, U u) throws Exception;
}

在使用中把方法放入map中 按参数调用数据

/**
 * date: 2022-10-30
 *
 * @author xuhb
 **/
@Component
public class MetaService {

    private final Map<String, ParamFunction<String, Integer, String>> map = new HashMap<>(16);

    //这里可以用枚举优化
    @PostConstruct
    void initMap() {
        map.put("one", this::oneMethod);
        map.put("two", this::towMethod);
    }

    public String getResult(String type, String s, Integer integer) throws Exception {
        return map.getOrDefault(type, this::defaultMethod).apply(s, integer);
    }

    private String oneMethod(String s, Integer integer) {
        return s + integer;
    }

    private String towMethod(String s, Integer integer) {
        return integer + s;
    }

    /**
     * 空对象模式
     *
     * @param s       参数一
     * @param integer 参数二
     * @return java.lang.String  返回
     */
    private String defaultMethod(String s, Integer integer) throws Exception {
        throw new Exception("参数错误");
    }

用法

@SpringBootTest
class MetaServiceTest {

    @Resource
    private MetaService metaService;

    @Test
    void  test1() throws Exception {
        String result = metaService.getResult("one", "s", 2);
    }

}

可以按需扩展

标签:return,String,spring,getBean,private,integer,java,设计模式,public
From: https://www.cnblogs.com/funkboy/p/16841301.html

相关文章

  • Spring源码-context:component-scan解析
    调用AbstractApplicationContext.refresh()刷新容器,会调用obtainFreshBeanFactory()获取ConfigurableListableBeanFactory。会去调用loadBeanDefinitions()方法解析xml文件......
  • Java_JVM探究
    请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?什么是OOM,什么是栈溢出StackOverflowError?怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取,怎么分析Dump文件?谈......
  • java.lang.NoClassDefFoundError
    问题描述:最近对JavaWeb进行了简单复习,在对照以往笔记写好了一个Servlet服务时发现无法启动该项目服务。针对java.lang.NoClassDefFoundError:javax/servlet/http/HttpSer......
  • springboot源码剖析(一) 总体启动流程
    前言  之前阅读STL(C++)源码的时候,有所感悟:大佬的代码总会实践到部分设计模式、新型语法特性,亦或是精巧的算法和数据结构。     读源码的技巧:大......
  • 找到多个名为spring_web的片段。这是不合法的相对排序。有关详细信息,请参阅Servlet规
    问题描述:解决办法:1:检查pom.xml中是否包含多个spring-web字段;2:删除掉多余的spring-web.jar,保留一个即可;......
  • Spring事务回滚的两种方法
    ##方法一1.使用@Transaction来配置自动回滚,可以配置在类上,也可以配置在方法上(作用域不同),但对final或private修饰的方法无效,且该类必须是受spring所管控的,也就是被已经被注......
  • Spring源码分析之AOP
    AOP是什么面向切面的程序设计(Aspect-orientedprogramming,AOP,又译作面向方面的程序设计、剖面导向程序设计),是计算机科学中的一种程序设计思想,旨在将横切关注点与业务主体进......
  • 【设计模式】-python-创建型
    单例模式只允许一个类只有一个实例。先了解一下下python的init()方法和new()方法init不是实例化一个类第一个调用的方法,第一个调用的方法是new方法,new方法返回一个......
  • SpringMVC源码-DispatcherServlet初始化
    web容器启动后会实例化Servlet,会执行Servlet的init方法且只会执行一次。后续调用doService处理客户请求。DispatcherServlet的构造方法publicDispatcherServlet(){ su......
  • 第四章 SpringBoot 底层机制
    搭建SpringBoot底层机制开发环境1、创建Maven项目lzw-springboot2、导入相关依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.o......