zoukankan      html  css  js  c++  java
  • 设计模式--策略模式

    一、为何策略呢

                 举个栗子:上班族(Person)上班,可以骑车、坐公交、坐地铁,打滴滴或者步行,对Person来说,这些出行方式都是一个策略。

     在软件领域也就是说一个类的一个动作方法,有不通的执行方式。比如很多个Person进行排序。可以按照身高来排序,按照体重来排序,按照年龄来排序。那Person 中的sort方法就是一种动作,按体重、身高,年龄排序就是不同的策略。

         3. 优点

    • 策略可以自由切换
    • 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
    • 扩展性良好,增加一个策略只需实现接口即可

      4. 缺点

    • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
    • 所有的策略类都需要对外暴露

      5. 使用场景

    • 多个类只有算法或行为上稍有不同的场景
    • 算法需要自由切换的场景
    • 需要屏蔽算法规则的场景

    二、策略模式的实现

    以商场促销为例使用策略模式实现商场促销算法。UML图如下

    1. 上下文类

      首先声明一个CashSuper对象,通过构造方法,传入具体的收费策略,getResult()方法的功能为根据收费策略的不同获得计算结果。

    public class CashContext {
        
        private CashSuper cashSuper;
        
        public CashContext(CashSuper cashSuper) {
            this.cashSuper = cashSuper;
        }
        
        public double getResult(double money) {
            return cashSuper.acceptCash(money);
        }
    
    }

    2. 现金收费抽象类

      策略类,为抽象类,抽象出收费的方法供子类实现。

    1 public abstract class CashSuper {
    2     public abstract double acceptCash(double money);
    3  
    4  }

    3. 正常收费子类

    1 public class CashNormal extends CashSuper {
    2 
    3     @Override
    4     public double acceptCash(double money) {
    5         return money;
    6     }
    7 
    8 }

    4. 打折收费子类

      打折活动,根据折扣返回打折后的价格。

     1 public class CashRebate extends CashSuper {
     2     
     3     private double moneyRebate = 1;    //折扣
     4     
     5     public CashRebate(double moneyRebate) {
     6         this.moneyRebate = moneyRebate;
     7     }
     8 
     9     @Override
    10     public double acceptCash(double money) {
    11         return money * moneyRebate;
    12     }
    13 
    14 }

    5. 返利收费子类

    返利活动,输入返利条件和返利值,比如满300返100,moneyCoditation为300,moneyReturn为100。

     result = money - Math.floor(money / moneyConditation) * moneyReturn; 的意思为,如果当前金额大于等于返利条件,则使用当前金额减去返利值。

     1 public class CashReturn extends CashSuper {
     2 
     3     private double moneyConditation = 0.0;    //返利条件
     4     private double moneyReturn = 0.0d;    //返利值
     5     
     6     public CashReturn(double moneyConditation, double moneyReturn) {
     7         this.moneyConditation = moneyConditation;
     8         this.moneyReturn = moneyReturn;
     9     }
    10 
    11     @Override
    12     public double acceptCash(double money) {
    13         double result = money;
    14         
    15         if (money >= moneyConditation) {
    16             result = money - Math.floor(money / moneyConditation) * moneyReturn;
    17         }
    18         
    19         return result;
    20     }
    21 
    22 }

    6. Client客户端

      下面写一个简单的程序测试一下上方编写的代码。

     1 public class Client {
     2     
     3     public static void main(String[] args) {
     4         CashContext cashContext = null;
     5         
     6         Scanner scanner = new Scanner(System.in);
     7         System.out.print("请输入打折方式(1/2/3):");
     8         int in = scanner.nextInt();
     9         String type = "";
    10         
    11         switch (in) {
    12             case 1:
    13                 cashContext = new CashContext(new CashNormal());
    14                 type += "正常收费";
    15                 break;
    16                 
    17             case 2:
    18                 cashContext = new CashContext(new CashReturn(300, 100));
    19                 type += "满300返100";
    20                 break;
    21                 
    22             case 3:
    23                 cashContext = new CashContext(new CashRebate(0.8));
    24                 type += "打8折";
    25                 break;
    26     
    27             default:
    28                 System.out.println("请输入1/2/3");
    29                 break;
    30         }
    31         
    32         double totalPrices = 0;
    33         
    34         System.out.print("请输入单价:");
    35         double price = scanner.nextDouble();
    36         System.out.print("请输入数量:");
    37         double num = scanner.nextDouble();
    38         totalPrices = cashContext.getResult(price * num);
    39         
    40         System.out.println("单价:" + price + ",数量:" + num + ",类型:" + type + ",合计:" + totalPrices);
    41         
    42         scanner.close();
    43     }
    44 
    45 }

    ==========================================================================           如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞】,希望我们一起在架构的路上,并肩齐行
    ==========================================================================
  • 相关阅读:
    Swing中GridBagLayout布局的使用
    Android下Slidingmenu和actionbarsherlock的使用
    Swing基础知识
    Android下的ActionBar
    android下ADT的更新
    spark插件入门完整版本
    IOS开发准备 资料集锦
    Java调用本地浏览器
    Android源码在线查看网址
    Android中ProgressBar
  • 原文地址:https://www.cnblogs.com/amberJava/p/12382913.html
Copyright © 2011-2022 走看看