美文网首页
行为型-策略模式

行为型-策略模式

作者: 程序男保姆 | 来源:发表于2020-05-20 19:06 被阅读0次
  • 意图:

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

  • 主要解决:

在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

  • 何时使用:

一个系统有许多许多类,而区分它们的只是他们直接的行为。

  • 如何解决:

将这些算法封装成一个一个的类,任意地替换。

  • 关键代码:

实现同一个接口。结合spring的话还需要hashmap
整体与享元模式几分类似,但是享元模式关注点是复用对象而策略模式的关注点是执行策略

  • 应用实例:

1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
3、JAVA AWT 中的 LayoutManager。

  • 优点:

1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。

  • 缺点:

1、策略类会增多。
2、所有策略类都需要对外暴露。

  • 使用场景:

1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

  • 注意事项:

如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

类图

策略模式 image.png
public class Context {
   private Strategy strategy;
 
   public Context(Strategy strategy){
      this.strategy = strategy;
   }

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

public interface Strategy {
   public int doOperation(int num1, int num2);
}

public class OperationMultiply implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 * num2;
   }
}

public class OperationSubtract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}


public class StrategyPatternDemo {
   public static void main(String[] args) {
      Context context = new Context(new OperationAdd());
      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationSubtract());
      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

      context = new Context(new OperationMultiply());
      System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
   }
}

下面策略模式结合spring 开始替换 if else

** 策略 **


public interface  AbstractStrategy {
     public void process(OrderDTO orderDTO);
}

** 策略的实施者2 **

@Service
@OrderTypeAnnotation(orderType = OrderTypeEnum.BOOKING)
public class BookingOrderStrategy implements AbstractStrategy {
    @Override
    public void process(OrderDTO orderDTO) {
        System.out.println("取消预约订单");
    }
}

** 策略的实施者2 **

@Service
@OrderTypeAnnotation(orderType = OrderTypeEnum.INSTANT)
public class InstantOrderStrategy implements AbstractStrategy {
    @Override
    public void process(OrderDTO orderDTO) {
        System.out.println("取消即时订单");
    }
}

** 策略者 核心**


@Service
public class StrategyContext  implements ApplicationContextAware {
    private Map<OrderTypeEnum, AbstractStrategy> strategyMap = new HashMap<>();


    /**
     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
     *
     * @param applicationContext
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        postProcessBeanFactory(applicationContext);
    }

    /***
     * spring bean 初始化完成后调用
     */
    public void postProcessBeanFactory(ApplicationContext applicationContext) {
        Reflections reflections = new Reflections(StrategyPackage.class);
        Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(OrderTypeAnnotation.class);
        for (Class<?> clazz : classSet) {
            AbstractStrategy bean = (AbstractStrategy) applicationContext.getBean(clazz);

            OrderTypeAnnotation annotation = clazz.getAnnotation(OrderTypeAnnotation.class);

            strategyMap.put(annotation.orderType(), bean);
        }
    }

    /**
     * 根据指标类型获取对应的实现类
     *
     * @param orderTypeEnum
     *
     * @return
     */
    public AbstractStrategy getStrategy(OrderTypeEnum orderTypeEnum) {
        if (orderTypeEnum == null) {
            throw new IllegalArgumentException("codeEnum can't be null");
        }

        if (CollectionUtils.isEmpty(strategyMap)) {
            throw new IllegalArgumentException("strategy map is empty,please check your strategy package path");
        }

        AbstractStrategy strategy = strategyMap.get(orderTypeEnum);

        Assert.notNull(strategy, "can't find AbstractStrategy using {}"+ orderTypeEnum.toString());

        return strategy;
    }


}

** 实体类 **

public class OrderDTO {
}

** 注解类 **

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface OrderTypeAnnotation {
    OrderTypeEnum orderType();
}

** 枚举类 **


public enum OrderTypeEnum {
    BOOKING,INSTANT
}

** 包名 **


public interface StrategyPackage {
}

** 测试类 **

@RestController
public class CancelOrderStrategyService {

    @Autowired
    private StrategyContext context;

    @RequestMapping("/a")
    public void process() {
        OrderTypeEnum orderTypeEnum = OrderTypeEnum.BOOKING;
        AbstractStrategy strategy = context.getStrategy(orderTypeEnum);
        strategy.process(new OrderDTO());
    }
}

相关文章

  • 设计模式[13]-策略模式-Strategy Pattern

    1.策略模式简介 策略模式(Strategy Patter)是行为型(Behavioral)设计模式,策略模式封装...

  • Android设计模式——策略模式(十一大行为型)

    1.策略模式介绍 策略模式(Strategy Pattern),是十一大行为型设计模式之一。 在开...

  • 策略模式(行为型)

    概念定义一系列算法,将这些算法封装起来,使他们可以相互替换,同时算法的修改与更新不影响调用它的对象(Context...

  • 行为型-策略模式

    意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。 主要解决: 在有多种算法相似的情况下,使...

  • 策略模式 - 行为型

    一、策略模式的定义定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它...

  • 23.策略模式(行为型)

    策略模式(行为型) 原书链接设计模式(刘伟) 适应算法灵活性而产生的设计模式——策略模式。 一、相关概述 1). ...

  • 行为型设计模式-策略模式

    定义 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换 解决问题 在有多种算法相似的情况下,使用 i...

  • 行为型设计模式 - 策略模式

    定义一系列的算法,把它们封装起来,并且使它们可相互替换; 在有多种算法相似的情况下,使用if...else复杂且难...

  • 行为型设计模式.策略模式

    概念理解 现实世界中,完成一项任务,往往可以选择不同的方式,每一种方式被称为一个策略,我们可以根据环境或者条件的不...

  • 行为型设计模式 — 策略模式

    一件事实是一条没有性别的真理。 — 纪伯伦 写在前面 策略模式的定义:定义一系列的算法,把每一个算法封装起来,并且...

网友评论

      本文标题:行为型-策略模式

      本文链接:https://www.haomeiwen.com/subject/kannohtx.html