• 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("
    ---------------------------");
    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("
    ---------------------------");
    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)…………

  • 相关阅读:
    好文推荐
    高效词频分析
    内网渗透技巧:判断机器真实外网IP的5种方法总结
    禁用substr、substring、mid函数的sql注入脚本
    内网文件传输
    工作
    我是如何逃过所有杀软进行内网端口转发的
    扎克伯格开发的家用AI: Jarvis
    Python初学者之网络爬虫(二)
    Python初学者之网络爬虫
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8334506.html
Copyright © 2020-2023  润新知