GOF23设计模式之策略模式(strategy)

一、策略模式概述

  策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一种算法解决一个问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法。

  策略模式的本质:

    分离算法,选择实现。

二、策略模式场景导入

  某公司市场部在接单时根据不同的客户进行报价,可以划分为以下几种类型:

    (1)新客户小批量报价

    (2)新客户大批量报价

    (3)老客户小批量报价

    (4)老客户大批量报价

  当遇到这种情况时,可以采用策略模式实现。

三、使用普通方式实现报价操作

 1 /**
 2  * 普通方式实现报价 
 3  * @author CL
 4  *
 5  */
 6 public class TestStrategy {
 7     
 8     public double getPrice(String type, double price) {
 9         if (type.equals("新客户小批量")) {
10             System.out.println("不打折!");
11             return price;
12         }
13         
14         if (type.equals("新客户大批量")) {
15             System.out.println("打九折!");
16             return price * 0.9;
17         }
18         
19         if (type.equals("老客户小批量")) {
20             System.out.println("打八五折!");
21             return price * 0.85;
22         }
23         
24         if (type.equals("老客户大批量")) {
25             System.out.println("打八折!");
26             return price * 0.8;
27         }
28             
29         return price;
30     }
31     
32     public static void main(String[] args) {
33         TestStrategy strategy = new TestStrategy();
34         
35         System.out.printf("您该报价:%6.2f", strategy.getPrice("老客户小批量", 998));
36 
37         System.out.println("\n---------------------------");
38         
39         System.out.printf("您该报价:%6.2f", strategy.getPrice("新客户大批量", 1024));
40      }
41 
42 }

  控制台输出:

打八五折!
您该报价:848.30
---------------------------
打九折!
您该报价:921.60

  注意:实现起来很容易,符号一般开发人员的思路。但是,假如类型很多,算法比较复杂时,整个条件语句的代码就变得很长,难于维护。如果有新增类型,就需要频繁的修改代码。

       不符合开闭原则!

四、使用策略模式实现报价操作

 1 /**
 2  * 策略模式
 3  * @author CL
 4  *
 5  */
 6 public interface Strategy {
 7     
 8     public double getPrice(double originalCost);
 9 
10 }
 1 /**
 2  * 新客户小批量
 3  * @author CL
 4  *
 5  */
 6 public class NewCustomerFewStrategy implements Strategy {
 7 
 8     @Override
 9     public double getPrice(double originalCost) {
10         System.out.println("不打折!");
11         return originalCost;
12     }
13 
14 }
 1 /**
 2  * 新客户大批量
 3  * @author CL
 4  *
 5  */
 6 public class NewCustomerManyStrategy implements Strategy {
 7 
 8     @Override
 9     public double getPrice(double originalCost) {
10         System.out.println("打九折!");
11         return originalCost * 0.9;
12     }
13 
14 }
 1 /**
 2  * 老客户小批量
 3  * @author CL
 4  *
 5  */
 6 public class OldCustomerFewStrategy implements Strategy {
 7 
 8     @Override
 9     public double getPrice(double originalCost) {
10         System.out.println("打八五折!");
11         return originalCost * 0.85;
12     }
13 
14 }
 1 /**
 2  * 老客户大批量
 3  * @author CL
 4  *
 5  */
 6 public class OldCustomerManyStrategy implements Strategy {
 7 
 8     @Override
 9     public double getPrice(double originalCost) {
10         System.out.println("打八折!");
11         return originalCost * 0.8;
12     }
13 
14 }
 1 /**
 2  * 负责和具体的策略类交互
 3  * 使策略模式,使具体的算法和直接的客户调用分离,使算法可以独立于客户端进行独立变化。
 4  * 可以通过构造器注入策略对象的引用,也可以通过set方法注入策略对象的引用。
 5  * 如果使用spring的依赖注入功能,还可以通过配置文件,动态地注入不同的策略对象,动态的切换不同的算法。
 6  * @author CL
 7  *
 8  */
 9 public class Context {
10 
11     private Strategy strategy;
12 
13     //通过构造器注入
14     public Context(Strategy strategy) {
15         this.strategy = strategy;
16     }
17 
18     //通过set方法注入
19     public void setStrategy(Strategy strategy) {
20         this.strategy = strategy;
21     }
22     
23     public void printPrice(double originalCost) {
24         System.out.printf("您该报价:%6.2f", strategy.getPrice(originalCost));
25     }
26     
27 }

  测试:

 1 /**
 2  * 测试策略模式
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7 
 8     public static void main(String[] args) {
 9         Strategy strategy = new OldCustomerFewStrategy();    //老客户小批量
10         Context context = new Context(strategy);
11         
12         context.printPrice(998);
13         
14         System.out.println("\n---------------------------");
15         
16         Strategy strategy2 = new NewCustomerManyStrategy();    //新客户大批量
17         Context context2 = new Context(strategy2);
18         
19         context2.printPrice(1024);
20         
21     }
22 }

  控制台输出:

打八五折!
您该报价:848.30
---------------------------
打九折!
您该报价:921.60

五、策略模式常见开发应用场景

  (1)市场系统中的报价功能;

  (2)医保系统中根据不同的人缴纳不同的保险费用;

  (3)…………

posted @ 2018-01-23 11:14  C3Stones  阅读(619)  评论(0编辑  收藏  举报