需求
目前在改造项目中的一个功能,简化一下业务逻辑 具体需求如下
现在是需要提供一个接口,接口会传入一个mark标识 以及一个url 需要根据不同的mark标识的策略 在url后面拼接一些不同的参数 再将url返回。
-
常见的做法就是去使用 if/else 判断,看看url后面该拼什么参数 拼接后返回
-
考虑到该接口后面可能需要适配更多的拼接策略 我使用策略模式对 if/else 进行了优化 具体代码如下
代码
首先定义处理url拼接的service 为了方便拓展 我们设计为一个接口,以及两个实现类,实现类分别代表了不同的拼接策略
如下 分为A、B两种策略,A策略是需要拼接userId这个参数 值为a,B策略是需要拼接uuid这个参数 值为b(这里只是为了演示)
java
public interface LinkRedirectService {
String getUrl(Map<String,String> map);
}
@Service("urlA")
public class UrlALinkRedirectServiceImpl implements LinkRedirectService {
@Override
public String getUrl(Map<String, String> map) {
return map.get("url") + "?userId=a";
}
}
@Service("urlB")
public class UrlBExamLinkRedirectServiceImpl implements LinkRedirectService {
@Override
public String getUrl(Map<String, String> map) {
return map.get("url") + "?uuid=b";
}
}
接下来 定义一个策略类 在初始化时 把上面的实现类都加载进内部的Map集合,bean名称为key、对象为value
java
@Component
public class LinkRedirectServiceStrategy {
@Autowired
ApplicationContext applicationContext;
private static Map<String, LinkRedirectService> map = new HashMap<>();
//bean初始化时 获取到所有LinkRedirectService类型的bean 注入到map集合
@PostConstruct
public void init() {
map = applicationContext.getBeansOfType(LinkRedirectService.class);
}
//提供getUrl方法 供Controller层调用 直接根据传入的mark 找到对应的实现类 去执行拼接逻辑 避免了if/else
public String getUrl(Map<String, String> param) {
String mark = param.get("mark");
if (map.containsKey(mark)) {
return map.get(mark).getUrl(param);
}
return param.get("url");
}
}
控制器层 注入这个 LinkRedirectServiceStrategy 、调用getUrl传入参数即可
后续如果再需要添加新的策略,只需要为 LinkRedirectService 接口 增加新的实现类即可,同时还需要注意:实现类的bean名称需要和接口传入的mark保持一致。