二、策略模式-商场促销活动

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

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

一、面向过程的实现方式

 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来承担选择的工作,最大化地减轻了客户端的职责。
  • 任何需求都是需要成本的,日后会讲到反射机制,可以不用选择,以后再说咯!

原文地址:https://www.cnblogs.com/zuolanlan/p/9990495.html

时间: 2024-10-08 13:23:06

二、策略模式-商场促销活动的相关文章

二 策略模式

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合 策略模式封装了变化 在实践中,我们发现可以用它来封装几乎任类型的规则,只要在分析过程中听到需要在不同时间应用到不同的业务规则,就考虑使用策略模式来处理这种变化的可能 商场促销例子 现金收费抽象类 using System; using System.Collections.Generic; using System.Linq;

领域驱动系列二策略模式的应用

一.简介 随着模型的不断扩大,发现模型中不单单只有"名词",还有许多"谓词",简言之,就是领域知识中,会参杂者许多的业务规则,他们和实体一样,都扮演者领域模型中的核心角色. 所以我们在建立领域模型的时候,不单单只关注实体和值对象,业务规则也被纳入到了领域模型中,如果业务规则变化不频繁,我们可以使用硬编码来解决,但是实际开发中业务规则的变化往往是变化的非常频繁的.当然你可以使用大量的If else来解决这个问题,但是这种代码是很难维护的.而且会影响原先的业务,所以这个

设计模型之二策略模式

//strategy model //策略模式是一种定义一系列算法的方法 #include<iostream> using namespace std; //一个抽象的策略类 class Strategy{ public: virtual void algorithmInterface()=0; }; //三种不同策略 class StrategyA:public Strategy{ void algorithmInterface() { cout<<"A strateg

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

一.引言 平时去商场买东西,会遇到各种各样的商场促销活动,例如:黄金会员打9折,铂金会员打8折,钻石会员打7折...通常的做法,定义一个算法类,我们根据会员类型,使用if-else判断获得不同的算法.这样的确解决了问题,但是哪天商场新增活动了,要买300返100,我们就需要去修改算法类了,违背了"开放-封闭原则",我们认为这样的设计是不够友好的.这时我们可以考虑使用策略模式来解决这个问题 二.策略模式 定义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不

设计模式(1)--简单工厂模式、策略模式

1. 简单工厂模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. 先放图再解释.下图一是从<大话设计模式>中摘出来的.问题是:用任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果. 简单工厂模式实现的关键点有两个: 1. 继承:定义一个抽象父类“抽象产品”(Operation类

计算器软件的代码实现 (策略模式)

一 封装时策略模式的书写 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace shuxuefudao { class qita { public void qingkong() { File.WriteAllText("writer.txt", string.Empty); File.WriteAllText(&q

《大话设计模式》——读后感 (2)商场促销?——策略模式

 按照我的习惯,先看策略模式UML结构图: 从图中,我看到了Strategy类,还有具体的实现类,还有一个Context,感觉和简单工厂好像啊,只是名字不一样而已.此处,我还用接口. 什么是策略模式呢? 实现: 原文是针对商场促销进行各种各样的打折进行设计案例的,而大话设计模式中还提到: 等等,打折.返现等等一系列促销具体方式只是一些算法,而算法本身也是一种策略.那我在此就要偷懒了: Operation接口,OperationAdd.OperationDelete.OperationDIv.Op

第 2 章 商场促销——策略模式

背景:做一个商场收银软件 收费情形:正常收费.打八折.打七折.打五折 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少各种算法类与使用算法类之间的耦合. 策略模式的Strategy类参差为Context定义了一系列的可供重用的算法或行为.继承又助于析取出这些算法中的公共功能. 策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的借口单独测试. 当不同的行为堆砌在一个类中时,就很难避免使用条

商场促销——策略模式

策略模式(Strategy):它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户. “面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类”.打一折和打九折只是形式的不同,抽象分析出来,所有的打折算法都是一样的,所以打折算法应该是一类. Strategy类,定义所有支持的算法的公共接口. //抽象算法类 abstract class Strategy{ //算法方法 public ab