一. 背景
进行业务代码编写的时候,常常会出现两条线,但是两条线的大部分逻辑相同,仅是部分逻辑不一样。此时若使用一个class或一条线,针对不同的逻辑就必须要 if-else 来编写。这种编写方式的弊端:后续若再次出现一条线和已有的两条线大部分逻辑相同,仅有部分逻辑不一样,此时又需要在已有的代码中增加 if-else,一方面违背了开闭原则,另一方面代码可读性较差,维护成本也会变大,同时一个类很有可能会出现爆炸的现象。
基于以上,建议使用策略模式。
二. 示例
public interface IBaseInterface{ void menthod1(String strategyType) void menthod2(String strategyType) }
@Service("strategy1Service")
public class Strategy1 implements IBaseInterface{ private static final Logger log = LoggerFactory.getLogger(Strategy1 .class); @Override public void method1(String strategyType){ log.info("Strategy1 - method1"); } @Override public void method2(String strategyType){ log.info("Strategy1 - method2"); } }
@Service("strategy2Service")
public class Strategy2 implements IBaseInterface{ private static final Logger log = LoggerFactory.getLogger(Strategy2.class); @Override public void method1(String strategyType){ log.info("Strategy2 - method1"); } @Override public void method2(String strategyType){ log.info("Strategy2 - method2"); } }
@Service("strategy3Service")
public class Strategy3 implements IBaseInterface{ private static final Logger log = LoggerFactory.getLogger(Strategy3.class); @Override public void method1(String strategyType){ log.info("Strategy3 - method1"); } @Override public void method2(String strategyType){ log.info("Strategy3 - method2"); } }
public enum StrategyEnum { STRATEGY1("1","strategy1Service"), STRATEGY2("2","strategy2Service"), STRATEGY3("3","strategy3Service") ; private String strategyType; private String beanName; private StrategyEnum (String strategyType,String beanName){ this.strategyType = strategyType; this.beanName = beanName; }
public static StrategyEnum findByBeanName(String beanName) {
for(StrategyEnum value:StrategyEnum.values()) {
if(value.getBeanName().equals(beanName)) {
return value;
}
}
return null;
}
private String getStrategyType(){ return strategyType; } private String getBeanName(){ return beanName; } }
public class StrategyManager{ @Autowired private ApplicationContext applicationContext; @Override public void method1(String strategyType){ IBaseInterface instance = findBean(strategyType); instance.method1(strategyType); } @Override public void method2(String strategyType){ IBaseInterface instance = findBean(strategyType); instance.method2(strategyType); } private IBaseInterface findBean(String strategyType){ StrategyEnum strategy = StrategyEnum.findByBeanName(strategyType); if(null != strategy) { return (IBaseInterface) applicationContext.getBean(strategy.getBeanName()); } throw NullPointerException(); } }
三. 知识
1、UML图
说明:
以上使用了两种模式:门面模式 (屏蔽掉实现细节,外部只要使用该门面中的接口即可)+ 策略模式 (每个接口可以有不同的实现方式,根据需要选择某种实现方式)
(1) strategy1、strategy2、strategy3 均是 三种不同的实现,其实例通过 spring IOC 存储在 applicationContext 中。
(2) strategyManager 中会根据某个标记选择不同的实现方式(strategy1或strategy2或strategy3)