设计模式学习笔记(八、行为型-策略模式)

目录:

  • 什么是策略模式
  • 策略模式能用来干什么
  • 策略模式的实现方式
  • 场景示例

什么是策略模式

通过定义一系列类似的策略类,并将其分别封装起来,让他们可以互相替换的模式。

策略模式能用来干什么

策略模式可以使算法的变化独立于使用它们的客户端,解耦策略的定义创建使用这三部分。

策略模式的实现方式

1、策略的定义

 1 /**
 2  * 策略接口
 3  *
 4  * @author zhoude
 5  * @date 2020/4/18 19:02
 6  */
 7 public interface Strategy {
 8     /**
 9      * 策略算法接口
10      */
11     void algorithmInterface();
12 }
 1 /**
 2  * 具体的策略A
 3  *
 4  * @author zhoude
 5  * @date 2020/4/18 19:03
 6  */
 7 public class ConcreteStrategyA implements Strategy {
 8     @Override
 9     public void algorithmInterface() {
10         System.err.println("具体的策略A算法的实现");
11     }
12 }
 1 /**
 2  * 具体的策略B
 3  *
 4  * @author zhoude
 5  * @date 2020/4/18 19:03
 6  */
 7 public class ConcreteStrategyB implements Strategy {
 8     @Override
 9     public void algorithmInterface() {
10         System.err.println("具体的策略B算法的实现");
11     }
12 }

2、策略的创建

 1 /**
 2  * 策略工厂,用于创建具体的策略算法
 3  * cache:策略类无状态不需要每次new一个新的
 4  *
 5  * @author zhoude
 6  * @date 2020/4/18 19:07
 7  */
 8 public class StrategyFactoryCache {
 9     private static final Map<String, Strategy> STRATEGIES = new HashMap<>();
10 
11     static {
12         STRATEGIES.put("A", new ConcreteStrategyA());
13         STRATEGIES.put("B", new ConcreteStrategyB());
14     }
15 
16     public static Strategy getStrateg(String type) {
17         if (type == null || type.isEmpty()) {
18             throw new IllegalArgumentException("type should not be empty.");
19         }
20         return STRATEGIES.get(type);
21     }
22 }
 1 /**
 2  * 策略工厂,用于创建具体的策略算法
 3  * cache:策略类有状态需要每次new一个新的
 4  *
 5  * @author zhoude
 6  * @date 2020/4/18 19:07
 7  */
 8 public class StrategyFactory {
 9     public static Strategy getStrateg(String type) {
10         if (type == null || type.isEmpty()) {
11             throw new IllegalArgumentException("type should not be empty.");
12         }
13 
14         if ("A".equals(type)) {
15             return new ConcreteStrategyA();
16         } else if ("B".equals(type)) {
17             return new ConcreteStrategyB();
18         }
19 
20         return null;
21     }
22 }

一般来说若策略是有状态的,那我们可以将创建额对象缓存到工厂类中,用的时候直接返回,如StrategyFactoryCache。

如果是无状态的,那就需要每次new一个新的策略类,StrategyFactory。

3、策略的使用

 1 /**
 2  * 测试类
 3  *
 4  * @author zhoude
 5  * @date 2020/4/18 19:16
 6  */
 7 public class Test {
 8     public static void main(String[] args) throws IOException {
 9         configLoad();
10         staticLoad();
11     }
12 
13     /**
14      * 通过加载配置方式方式,动态获取策略类
15      *
16      * @throws IOException exception
17      */
18     private static void configLoad() throws IOException {
19         Properties properties = new Properties();
20         properties.load(new FileInputStream("behavior/src/strategy/strategy.properties"));
21         String type = properties.getProperty("strategy.config");
22         Strategy strategy = StrategyFactoryCache.getStrateg(type);
23         strategy.algorithmInterface();
24     }
25 
26     /**
27      * 静态指定策略类
28      */
29     private static void staticLoad() {
30         Strategy strategy = StrategyFactory.getStrateg("B");
31         if (strategy != null) {
32             strategy.algorithmInterface();
33         }
34     }
35 }

场景示例

场景:根据文件大小排序,文件里面全是整数,且都已逗号分隔。

根据文件不同大小选择不同策略:

  • [0, 6G),使用快排
  • [6G, 10G),使用外部排序
  • [10G, 100G),使用多线程外部排序
  • [100G, +无穷),使用MapReduce多机排序

代码示例:https://github.com/mrjdrs/design-patterns/tree/master/behavior/src/strategy/demo2

猜你喜欢

转载自www.cnblogs.com/bzfsdr/p/12727623.html
今日推荐