策略模式-商场促销活动

Posted zuolanlan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略模式-商场促销活动相关的知识,希望对你有一定的参考价值。

以商场收银为例,理解并实践“策略模式”。

  • 简单商场促销活动描述:营业员提供商品单价、数量、商场目前的活动(满减、打折等),计算用户最终需要支付的金额

一、面向过程的实现方式

 1 package secondStrategy;
 2 import java.text.DecimalFormat;
 3 public class StrategyTest {
 4        public static void main(String[] args) {
 5               // 营业员提供信息
 6               double total=0;
 7               double price=2;
 8               int num=3;
 9               String promotions="打8折";//或者“满100-30”
10               
11               // 计算待付金额
12               double totalPrice=price*num;
13               total=total+totalPrice;
14               
15               switch (promotions) {
16               case "打8折":total=total*0.8;break;
17               case "满100-30": total=total-(total/100)*30; // "/"取整。“%”取余
18               default:
19                      break;
20               }
21               DecimalFormat df = new DecimalFormat("#.##"); // 如果写成0.00,结果就一定是两个小数
22               System.out.println("单价:"+price+";数量:"+num+";原价:"+totalPrice+";活动:"+promotions+";活动价:"+df.format(total));
23               
24        }
25 }

缺点:当有新的活动时,就要不停地复制程序代码,新增一个类别,这使程序的重复性增加,可维护性变差。

 

二、通过简单工厂实现

1、UML图结构

技术分享图片

2、语言描述

  • 父类:现金收费抽象类CashSuper
      • 抽象方法:acceptCash( 原价){ return 活动价}
    • 子类:正常收费CashNormal、
      • 实现父类抽象方法:acceptCash( 原价){ return 原价}
    • 子类:打折类CashRebate
      • 私有属性:moneyRebate;
      • 构造方法:带moneyRebate的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价*moneyRebate}
    • 子类:满减类CashRerurn
      • 私有属性:moneyCondition; moneyReturn;
      • 构造方法:带上面俩参数的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价-满减价}
  • 工厂:CashFactory
    • createCashAccept( String type)
  • 客户端:price/ num / "活动type" 
      • 实例化
      • 输出

 

三、通过策略模式来设计

1、UML图结构

技术分享图片

 

2、文字描述

  • 父类策略类:CashSuper
      • 抽象方法:acceptCash( 原价){ return 活动价}
    • 具体策略子类1:正常收费CashNormal、
      • 实现父类抽象方法:acceptCash( 原价){ return 原价}
    • 具体策略子类2:打折类CashRebate
      • 私有属性:moneyRebate;
      • 构造方法:带moneyRebate的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价*moneyRebate}
    • 具体策略子类3:满减类CashRerurn
      • 私有属性:moneyCondition; moneyReturn;
      • 构造方法:带上面俩参数的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价-满减价}
  • Context类:CashContext
      • 私有属性:CashSuper cs;
      • 构造方法:CashContext( CashSuper csuper){ this....}
      • 取得金额方法: getResult(){ cs.acceptCash()}
  • 客户端:price/ num / "活动type" 
      • switch(type) : cc=new CashContext( new CashRebate( canshu1, canshu2))
      • cc.getResult()

四、策略模式与工厂模式相结合

1、UML图结构

技术分享图片

 

2、文字描述

  • 父类策略类:CashSuper
      • 抽象方法:acceptCash( 原价){ return 活动价}
    • 具体策略子类1:正常收费CashNormal、
      • 实现父类抽象方法:acceptCash( 原价){ return 原价}
    • 具体策略子类2:打折类CashRebate
      • 私有属性:moneyRebate;
      • 构造方法:带moneyRebate的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价*moneyRebate}
    • 具体策略子类3:满减类CashRerurn
      • 私有属性:moneyCondition; moneyReturn;
      • 构造方法:带上面俩参数的
      • 实现父类抽象方法:acceptCash( 原价){ return 原价-满减价}
  • Context类:CashContext
      • 私有属性:CashSuper cs;
      • 构造方法:CashContext( String type){ switch()}
      • 取得金额方法: getResult(){ cs.acceptCash()}
  • 客户端:price/ num / "活动type" 
      • new CashContext( type )

3、java代码实现

  • 父类策略类:CashSuper
1 package secondStrategy;
2 
3 public abstract class CashSuper {
4     public abstract double acceptCash(double money);
5 }

 

    • 具体策略子类1:正常收费CashNormal
 1 package secondStrategy;
 2 
 3 public class CashNormal extends CashSuper {
 4 
 5     @Override
 6     public double acceptCash(double money) {
 7         return money;
 8     }
 9 
10 }

 

    • 具体策略子类2:打折类CashRebate
 1 package secondStrategy;
 2 
 3 // 打折类
 4 public class CashRebate extends CashSuper {
 5     private double moneyRebate=0;
 6     // 构造方法,初始化时应传入折扣
 7     public  CashRebate(double moneyRe) {
 8         this.moneyRebate=moneyRe;
 9     }
10     @Override
11     public double acceptCash(double money) {
12         double result=0;
13         result=money*moneyRebate;
14         return result;
15     }
16 
17 }

 

    • 具体策略子类3:满减类CashRerurn
 
 1 package secondStrategy;
 2 
 3 public class CashReturn extends CashSuper {
 4     private double moneyCondition=0; //满减门槛
 5     private double moneyReturn=0;  // 满减金额
 6     
 7     public  CashReturn(double moneyCon,double moneyRe) {
 8         // TODO Auto-generated constructor stub
 9         this.moneyCondition=moneyCon;
10         this.moneyReturn=moneyRe;
11     }
12     
13     @Override
14     public double acceptCash(double money) {
15         double result=0;
16         result=money-(money/moneyCondition)*moneyReturn;
17         return result;
18     }
19 
20 }

 

  • Context类:CashContext
 1 package secondStrategy;
 2 
 3 public class CashContext {
 4     private CashSuper cSuper;
 5     public   CashContext( String type) {
 6         switch (type) {
 7         case "打8折": this.cSuper=new CashRebate(0.8);    break;
 8         case "满100-30": this.cSuper=new CashReturn(100,30);break;
 9         default:this.cSuper=new CashNormal();
10             break;
11         }    
12     }
13     public double getResult(double money){
14         return this.cSuper.acceptCash(money);
15     }
16 }

 

  • 客户端:
package secondStrategy;

import java.text.DecimalFormat;

public class StrategyTest {
    public static void main(String[] args) {
        // 营业员提供信息
        double total=0;
        double price=2;
        int num=3;
        String promotions="打8折";//或者“满100-30”
        
        // 计算待付金额
        double totalPrice=price*num;
        total=total+totalPrice;
        
        switch (promotions) {
        case "打8折":total=total*0.8;break;
        case "满100-30": total=total-(total/100)*30; // "/"取整。“%”取余
        default:
            break;
        }
        DecimalFormat df = new DecimalFormat("#.##"); // 如果写成0.00,结果就一定是两个小数
        System.out.println("单价:"+price+";数量:"+num+";原价:"+totalPrice+";活动:"+promotions+";活动价:"+df.format(total));
        
    }
}

运行结果:

技术分享图片

五、总结说明

1、定义:策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同。它可以有相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
2、策略模式的Strategy类层次为Context定义了一系列可供重用的算法或行为。继承有助于析取出这些算法的公共功能——计费结果getResult()。
3、优点:
  • 它可以有相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合
  • 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试

4、特点:

  • 策略模式就是用来封装算法的,但在实践中,发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
  • 在基本的策略模式中,选择所用具体实现的职责有客户端对象承担,并转给策略模式的Context对象。本身虽然没有接触客户端需要选择判断的压力,但将简单工厂与策略模式结合之后,由Context来承担选择的工作,最大化地减轻了客户端的职责
  • 任何需求都是需要成本的,日后会讲到反射机制,可以不用选择,以后再说咯!

 

 

 

以上是关于策略模式-商场促销活动的主要内容,如果未能解决你的问题,请参考以下文章

设计模式四:策略模式

面向对象编程思想-策略模式

策略模式

设计模式之?策略模式

简说设计模式——策略模式

简说设计模式——策略模式