一、项目背景
在项目中,我们处理了各种类型的通知消息。在没有采用策略模式之前,代码中充斥了大量的 if-else 语句,这不仅让整个项目显得杂乱无章,还增加了后续维护的难度。为了解决这一问题,我们采用了 Map 和函数式接口来实现策略模式,从而显著提升了代码的可读性和可维护性。
例如下面这样,大家是不是经常见到
if (type == 1) {
// 业务1
}
else if (type == 2){
// 业务2
}
else {
// 业务3
}
开源地址,大家可以点点⭐
二、代码实现
- 首先我们创建一个实现各个操作的service,模拟业务操作。
import org.springframework.stereotype.Service;
@Service
public class NoticeTypeService {
public String email(String name){
return "电子邮件通知:" + name;
}
public String QQ(String name){
return "QQ通知:" + name;
}
public String ding(String name){
return "钉钉通知:" + name;
}
public String wechat(String name){
return "微信通知:" + name;
}
}
- 接着我们创建一个策略实现类,代码已写注释。还有不懂得可以评论区提问~
import com.demo.template.service.NoticeTypeService;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
public class NoticeStrategy {
@Resource
private NoticeTypeService noticeTypeService;
private Map<String, Function<String, String>> noticeTypeMap = new HashMap<>();
/**
* 初始化noticeTypeMap @PostConstruct会在bean的依赖注入完成之后被调用
*/
@PostConstruct
public void init() {
noticeTypeMap.put("qq", name -> noticeTypeService.QQ(name));
noticeTypeMap.put("email", name -> noticeTypeService.email(name));
noticeTypeMap.put("ding", name -> noticeTypeService.ding(name));
noticeTypeMap.put("wx", name -> noticeTypeService.wechat(name));
}
/**
* 根据不同的通知类型获取执行结果
*
* @param noticeType 通知类型
* @return noticeTypeService对应函数执行完的结果
*/
public String getAction(String noticeType, String name) {
// 从map中取出对应的函数
Function<String, String> result = noticeTypeMap.get(noticeType);
if (result != null) {
return result.apply(name);
}
return "不存在此类型";
}
}
- 最后我们创建一个controller,然后测试一下结果
import com.demo.template.config.NoticeStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/notice")
public class NoticeController {
@Resource
private NoticeStrategy strategy;
@GetMapping("/getType")
public String getWork(String type,String name) {
return strategy.getAction(type,name);
}
}
三、补充
有时候我们的函数需要传入多个参数的,可以自定义函数接口类,下面是示例
/**
* 自定义参数函数接口,想拓展几个就拓展几个,默认的Function只能传1个参数
* @param <paramA>
* @param <paramB>
* @param <Result>
*/
@FunctionalInterface
interface NoticeFunction<paramA, paramB, Result>{
Result apply(paramA a, paramB b);
}
四、最终效果
我们在地址栏输入下面的URL,最后浏览器显示如下
http://localhost:8888/api/notice/getType?type=qq&name=张三