Java学习笔记——设计模式之二.策略模式

明确是王道

    ——Clean Code

 类图:

先定义策略类

1 package cn.no2.strategy;
2 
3 public abstract class Strategy {
4 
5     //省略属性
6     //算法方法
7     public abstract void algrithmInterface();
8 }

在定义若干策略子类

 1 package cn.no2.strategy;
 2 
 3 public class ConcreteStrategyA extends Strategy {
 4 
 5     @Override
 6     public void algrithmInterface() {
 7         // TODO Auto-generated method stub
 8         System.out.println("算法A实现");
 9     }
10 
11 }
12 public class ConcreteStrategyB extends Strategy {
13 
14     @Override
15     public void algrithmInterface() {
16         // TODO Auto-generated method stub
17         System.out.println("算法B实现");
18     }
19 
20 }
21 public class ConcreteStrategyC extends Strategy {
22 
23     @Override
24     public void algrithmInterface() {
25         // TODO Auto-generated method stub
26         System.out.println("算法C实现");
27     }
28 
29 }

最后定义业务逻辑"上下文类"

 1 package cn.no2.strategy;
 2 
 3 public class BizContext {
 4 
 5     Strategy strategy = null;
 6 
 7     public BizContext(String type) {
 8         
 9         switch (type) {
10         case "策略A":
11             strategy= new ConcreteStrategyA();
12             break;
13         case "策略B":
14             strategy= new ConcreteStrategyB();
15             break;
16         case "策略C":
17             strategy= new ConcreteStrategyC();
18             break;
19         }
20     }
21     
22     public void ContextInterface(){
23         strategy.algrithmInterface();
24     }
25 }

测试类

 1 package cn.no2.strategy;
 2 
 3 public class _Text {
 4 
 5     public static void main(String[] args) {
 6         BizContext biz;
 7         biz = new BizContext("策略A");
 8         biz.ContextInterface();
 9         biz = new BizContext("策略B");
10         biz.ContextInterface();
11         biz = new BizContext("策略C");
12         biz.ContextInterface();
13     }
14 }

诚然,上面的程序只是明确了框架,并没有任何实际的业务逻辑.下面来写个需求

输入单价、数量、计价方式,其中计价方式就是策略:

策略1:正常收费

策略2:打X折

策略3:满X元减Y元

输出结果。

上代码:

Strategy类:

 1 package cn.no2.strategy.instance;
 2 
 3 public abstract class Strategy {
 4 
 5     private double unitPrice;
 6     private int count;
 7 
 8     public double getUnitPrice() {
 9         return unitPrice;
10     }
11 
12     public void setUnitPrice(double unitPrice) {
13         this.unitPrice = unitPrice;
14     }
15 
16     public int getCount() {
17         return count;
18     }
19 
20     public void setCount(int count) {
21         this.count = count;
22     }
23 
24     //计算结果,返回double值
25     public abstract double algrithmInterface();
26     
27 }

其子类:

 1 package cn.no2.strategy.instance;
 2 
 3 public class NomalStrategy extends Strategy {
 4 
 5     @Override
 6     public double algrithmInterface() {
 7         // 使用清晰规范的代码,定义变量,计算,返回
 8         double result = 0;
 9         result = this.getUnitPrice()*this.getCount();
10         return result;
11     }
12 
13 }
14 public class DiscountStrategy extends Strategy {
15 
16     private double discount;
17     
18     public DiscountStrategy(double discount) {
19         super();
20         this.discount = discount;
21     }
22 
23     @Override
24     public double algrithmInterface() {
25         // 这里重写方法不能传入参数,所以需要定义该子类特有的属性,折扣
26         double result = 0;
27         result = this.getUnitPrice()*this.getCount()*discount;
28         return result;
29     }
30 
31 }
32 public class FullReduceStrategy extends Strategy {
33 
34     double full;
35     double reduction;
36     
37     public FullReduceStrategy(double full, double reduction) {
38         super();
39         this.full = full;
40         this.reduction = reduction;
41     }
42 
43     @Override
44     public double algrithmInterface() {
45         // TODO Auto-generated method stub
46         double result = this.getUnitPrice()*this.getCount();
47         if (result >= full) {
48             result -= reduction;
49         }
50         return result;
51     }
52 
53 }

业务逻辑类:

 1 package cn.no2.strategy.instance;
 2 
 3 public class BizContext {
 4 
 5     private Strategy strategy = null;
 6     
 7     public BizContext(String type) {
 8         
 9         switch (type) {
10         case "正常收费":
11             strategy= new NomalStrategy();
12             break;
13         case "打8.5折":
14             strategy= new DiscountStrategy(8.5);
15             break;
16         case "满300减100":
17             strategy= new FullReduceStrategy(300,100);
18             break;
19         }
20     }
21     //彻底封装Strategy类
22     public void initStrategy(double unitPrice,int count) {
23         strategy.setUnitPrice(unitPrice);
24         strategy.setCount(count);
25     }
26     //这里实现的对strategy的封装,调用者只调用BizContext自己的方法
27     public double ContextInterface(){
28         return strategy.algrithmInterface();
29     }
30 }

Test类:

 1 package cn.no2.strategy.instance;
 2 
 3 import java.util.Scanner;
 4 
 5 public class _Text {
 6 
 7     public static void main(String[] args) {
 8         Scanner sc = new Scanner(System.in);
 9         System.out.println("请输入单价:");
10         double unitPrice = sc.nextDouble();
11         System.out.println("请输入数量:");
12         int count = sc.nextInt();
13         System.out.println("请输入策略:(正常收费,打8.5折,满300减100)");//这里如果改动,只需增加BizContext的业务逻辑
14         String strategy = sc.next();
15         BizContext biz = new BizContext(strategy);
16         biz.initStrategy(unitPrice,count);
17         double result = biz.ContextInterface();
18         System.out.println("总价是:"+result);
19         sc.close();
20     }
21 }

以上是策略模式的实际应用

策略模式与简单工厂对比:

简单工厂模式:客户端传一个条件进工厂类,工厂类根据条件创建相应的产品类对象,客户端使用该产品类对象.工厂类依赖产品类

策略模式:客户端创建一个Context类对象,并通过传入参数使用该对象。Context类中聚合了产品类,没有依赖关系

 

原文地址:https://www.cnblogs.com/tomasman/p/6848489.html