策略模式
使用策略模式去除业务代码中的 if else
- 抽象出业务处理器以及支持的各种业务类型
- 将各业务处理器和其支持的业务类型绑定
- 各业务处理器的实现
- 测试
最近在维护一个商城项目,对接是的各第三方购物平台,其中处理下单的类中包含了大量的if else语句
public void order(String platform) {
if ("taobao".equals(platform)) {
// 淘宝下单
} else if ("jingdong".equals(platform)) {
// 京东下单
} else if ("weipinhui".equals(platform)) {
// 唯品会下单
} else {
throw new RuntimeException("未知的业务类型");
}
}
看起来虽然思路清晰,但是加上具体下单实现以后代码就显得非常臃肿,而且每次接入新的平台后都要修改order方法,可扩展性就很差了,违背了开闭原则。可以使用策略模式来消除这些 if else
-
抽象出业务处理器以及支持的各种业务类型
package com.example.demo.service; /** * @Author: junwe * @Date: 2021/1/23 17:59 */ public interface OrderStrategy { /** * 抽象出的业务处理器 */ void order(); /** * 支持的类型,用于绑定业务处理器 * @return */ String[] support(); }
-
将各业务处理器和其支持的业务类型绑定
package com.example.demo.service; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; /** * @Author: junwe * @Date: 2021/1/23 18:09 */ @Component public class OrderStrategyChoose implements ApplicationContextAware { Map<String, OrderStrategy> strategyMap = new HashMap<>(); public OrderStrategy choose(String type) { return strategyMap.get(type); } /** * 将支持的业务类型和对应的业务处理器放入map中 * 因为是从spring容器中获取获取OrderStrategy类型的业务处理器,所以各业务处理器中@Component注解不能少 */ @PostConstruct public void register() { Map<String, OrderStrategy> beansOfType = context.getBeansOfType(OrderStrategy.class); for (OrderStrategy orderStrategy : beansOfType.values()) { for (String supportType : orderStrategy.support()) { strategyMap.put(supportType, orderStrategy); } } } private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } }
-
各业务处理器的实现
package com.example.demo.service.impl; import com.example.demo.service.OrderStrategy; import org.springframework.stereotype.Component; /** * @Author: junwe * @Date: 2021/1/23 18:05 */ @Component public class TaobaoOrderStrategy implements OrderStrategy { @Override public void order() { System.out.println("淘宝下单策略"); } @Override public String[] support() { return new String[] {"taobao"}; } }
package com.example.demo.service.impl; import com.example.demo.service.OrderStrategy; import sun.misc.Contended; /** * @Author: junwe * @Date: 2021/1/23 18:08 */ @Contended public class JDOrderStrategy implements OrderStrategy { @Override public void order() { System.out.println("京东下单策略"); } @Override public String[] support() { return new String[] {"jingdong"}; } }
-
测试
package com.example.demo; import com.example.demo.service.OrderStrategy; import com.example.demo.service.OrderStrategyChoose; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; @SpringBootTest class DemoApplicationTests { @Resource private OrderStrategyChoose strategyChoose; @Test void orderTest() { String type = "taobao"; OrderStrategy orderStrategy = strategyChoose.choose(type); if (orderStrategy == null) { throw new RuntimeException("未匹配的业务类型"); } orderStrategy.order(); } }