设计模式--策略模式

一、为何策略呢

             举个栗子:上班族(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 }

==========================================================================           如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞】,希望我们一起在架构的路上,并肩齐行
==========================================================================
原文地址:https://www.cnblogs.com/amberJava/p/12382913.html