设计模式(一)之策略模式

 一. 背景

     进行业务代码编写的时候,常常会出现两条线,但是两条线的大部分逻辑相同,仅是部分逻辑不一样。此时若使用一个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) 

原文地址:https://www.cnblogs.com/sandyflower/p/14085916.html