java spring项目中使用设计模式和函数式编程的思想去除业务逻辑中的if else判断
如果你开发项目时对项目之后的发展很清晰但仍陷入了为什么要用设计模式替换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);
}
}
可以按需扩展