商场促销--策略模式

news2024/11/25 12:26:53

1.1 商场收银软件

package com.lhx.design.pattern.test;

import java.util.Scanner;

public class Test {

	public static void main(String[] args){

		System.out.println("**********************************************");		
		System.out.println("《大话设计模式》代码样例");
		System.out.println();		

		double price = 0d; 		//商品单价
		int num = 0;			//商品购买数量
		double totalPrices = 0d;//当前商品合计费用
		double total = 0d;		//总计所有商品费用
		
		Scanner sc = new Scanner(System.in);

		do {
			System.out.println("请输入商品单价:");	
			price = Double.parseDouble(sc.nextLine());
			System.out.println("请输入商品数量:");	
			num = Integer.parseInt(sc.nextLine());
			System.out.println();	

			if (price>0 && num>0){

				totalPrices = price * num;
				total = total + totalPrices;
				
				System.out.println();	
				System.out.println("单价:"+ price + "元 	数量:"+ num +" 合计:"+ totalPrices +"元");	
				System.out.println();
				System.out.println("总计:"+ total+"元");	
				System.out.println();
			}
		}
		while(price>0 && num>0);

		System.out.println();		

		System.out.println("**********************************************");

	}
}

1.2 增加打折

1.正常收费 2.打八折 3.打七折
package com.lhx.design.pattern.test;

import java.util.Scanner;

public class Test {

	public static void main(String[] args){

		System.out.println("**********************************************");		
		System.out.println("《大话设计模式》代码样例");
		System.out.println();		

		int discount = 0; 		//商品折扣模式(1.正常收费 2.打八折 3.打七折)
		
		double price = 0d; 		//商品单价
		int num = 0;			//商品购买数量
		double totalPrices = 0d;//当前商品合计费用
		double total = 0d;		//总计所有商品费用
		
		Scanner sc = new Scanner(System.in);

		do {
			System.out.println("请输入商品折扣模式(1.正常收费 2.打八折 3.打七折):");	
			discount = Integer.parseInt(sc.nextLine());
			System.out.println("请输入商品单价:");	
			price = Double.parseDouble(sc.nextLine());
			System.out.println("请输入商品数量:");	
			num = Integer.parseInt(sc.nextLine());
			System.out.println();	

			if (price>0 && num>0){

				switch(discount){
					case 1:
						totalPrices = price * num;
						break;
					case 2:
						totalPrices = price * num * 0.8;
						break;
					case 3:
						totalPrices = price * num * 0.7;
						break;
				}
				
				total = total + totalPrices;
				
				System.out.println();	
				System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元");	
				System.out.println();
				System.out.println("总计:"+ total+"元");	
				System.out.println();
			}
		}
		while(price>0 && num>0);

		System.out.println();		

		System.out.println("**********************************************");

	}
}

1.3 简单工厂实现

商场的活动加大,需要有满300返回100的促销算法,又增加是700就要返200呢?或者说需要现在打三折,又要满300送80呢?

收费抽象类

package com.lhx.design.pattern.test;
//收费抽象类
public abstract class CashSuper {

    //收取费用的抽象方法,参数为单价和数量
    public abstract double acceptCash(double price,int num);
    
}
package com.lhx.design.pattern.test;

public class CashNormal extends CashSuper {

    //正常收费,原价返回
    public double acceptCash(double price,int num){
        return price * num;
    }
    
}
package com.lhx.design.pattern.test;

public class CashRebate extends CashSuper {

    private double moneyRebate = 1d;
    //打折收费。初始化时必需输入折扣率。八折就输入0.8
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }

    //计算收费时需要在原价基础上乘以折扣率
    public double acceptCash(double price,int num){
        return price * num * this.moneyRebate;
    }
    
}
package com.lhx.design.pattern.test;

public class CashReturn extends CashSuper {

    private double moneyCondition = 0d; //返利条件
    private double moneyReturn = 0d;    //返利值

    //返利收费。初始化时需要输入返利条件和返利值。
    //比如“满300返100”,就是moneyCondition=300,moneyReturn=100
    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }

    //计算收费时,当达到返利条件,就原价减去返利值
    public double acceptCash(double price,int num){
        double result = price * num;
        if (moneyCondition>0 && result >= moneyCondition)
            result = result - Math.floor(result / moneyCondition) * moneyReturn; 
        return result;
    }
    
}
package com.lhx.design.pattern.test;

public class CashFactory {

    //收费工厂
    public static CashSuper createCashAccept(int cashType){
        CashSuper cs = null;
        switch (cashType) {
            case 1:
                cs = new CashNormal();      //正常收费
                break;
            case 2:
                cs = new CashRebate(0.8d);  //打八折
                break;
            case 3:
                cs = new CashRebate(0.7d);  //打七折
                break;
            case 4:
                cs = new CashReturn(300d,100d);//满300返100
                break;

        }
        return cs;
    }
    
}

package com.lhx.design.pattern.test;

import java.util.Scanner;

public class Test {

	public static void main(String[] args){

		System.out.println("**********************************************");		
		System.out.println("《大话设计模式》代码样例");
		System.out.println();		

		int discount = 0; 		//商品折扣模式(1.正常收费 2.打八折 3.打七折)
		
		double price = 0d; 		//商品单价
		int num = 0;			//商品购买数量
		double totalPrices = 0d;//当前商品合计费用
		double total = 0d;		//总计所有商品费用
	
		Scanner sc = new Scanner(System.in);

		do {
			System.out.println("请输入商品折扣模式(1.正常收费 2.打八折 3.打七折 4.满300送100):");	
			discount = Integer.parseInt(sc.nextLine());
			System.out.println("请输入商品单价:");	
			price = Double.parseDouble(sc.nextLine());
			System.out.println("请输入商品数量:");	
			num = Integer.parseInt(sc.nextLine());
			System.out.println();	

			if (price>0 && num>0){

				//简单工厂模式根据discount的数字选择合适的收费类生成实例
				CashSuper csuper = CashFactory.createCashAccept(discount);
				//通过多态,可以根据不同收费策略计算得到收费的结果
				totalPrices = csuper.acceptCash(price,num);
				
				total = total + totalPrices;
				
				System.out.println();	
				System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元");	
				System.out.println();
				System.out.println("总计:"+ total+"元");	
				System.out.println();
			}
		}
		while(price>0 && num>0);

		System.out.println();
		System.out.println("**********************************************");

	}
}

1.4 策略模式

        我要是需要打五折和满500送200的促销活动,只要在现金工厂当中加两个条件,就okl ,准确的来说是收费对象生产工厂才正确,如果我现在需要增加一种商场促销手段,满100积分10点,以后到一定时候可以领取奖品如何做?

        "有了工厂,何难?加一个积分算法,构造方法有两个参数:条件和返点,让它继承CashSuper,再到现金工厂,哦,不对,是收费对象生成工厂里增加满100积分10点的分支条件,再到界面稍加改动,就行了。"

        简单工厂模式虽然也能解决这个问题,但这个模式只是解决对象的创建问题,而且由于工厂本身包括所有的收费方式,商场是可能经常性地更改打折额度和返利额度,每次维护或扩展收费方式都要改动这个工厂,以致代码需重新编译部署,这真的是很糟糕的处理方式,所以用它不是最好的办法。面对算法的时常变动,应该有更好的办法。好好去研究一下其他的设计模式,你会找到答案的。

策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

Strategy类,定义所有支持的算法的公共接口:

Context类,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。

客户端代码:

1.5 策略模式实现

package com.lhx.design.pattern.test;

public class CashContext {

    private CashSuper cs;   //声明一个CashSuper对象

    //通过构造方法,传入具体的收费策略
    public CashContext(CashSuper csuper){
        this.cs = csuper;
    }

    public double getResult(double price,int num){
        //根据收费策略的不同,获得计算结果
        return this.cs.acceptCash(price,num);
    }    
}
package com.lhx.design.pattern.test;

import java.util.Scanner;

public class Test {

	public static void main(String[] args){

		System.out.println("**********************************************");		
		System.out.println("《大话设计模式》代码样例");
		System.out.println();		

		int discount = 0; 		//商品折扣模式(1.正常收费 2.打八折 3.打七折)
		
		double price = 0d; 		//商品单价
		int num = 0;			//商品购买数量
		double totalPrices = 0d;//当前商品合计费用
		double total = 0d;		//总计所有商品费用
	
		Scanner sc = new Scanner(System.in);

		do {
			System.out.println("请输入商品折扣模式(1.正常收费 2.打八折 3.打七折 4.满300送100):");	
			discount = Integer.parseInt(sc.nextLine());
			System.out.println("请输入商品单价:");	
			price = Double.parseDouble(sc.nextLine());
			System.out.println("请输入商品数量:");	
			num = Integer.parseInt(sc.nextLine());
			System.out.println();	

			if (price>0 && num>0){

				
				CashContext cc = null;

				//根据用户输入,将对应的策略对象作为参数传入CashContent对象中
				switch(discount){
		            case 1:
		                cc = new CashContext(new CashNormal());
		                break;
		            case 2:
		                cc = new CashContext(new CashRebate(0.8d));
		                break;
		            case 3:
		                cc = new CashContext(new CashRebate(0.7d));
		                break;
		            case 4:
		                cc = new CashContext(new CashReturn(300d,100d));
		                break;
		        }
				
				//通过Context的getResult方法的调用,可以得到收取费用的结果
				//让具体算法与客户进行了隔离
				totalPrices = cc.getResult(price,num);
				
				total = total + totalPrices;
				
				System.out.println();	
				System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元");	
				System.out.println();
				System.out.println("总计:"+ total+"元");	
				System.out.println();
			}
		}
		while(price>0 && num>0);

		System.out.println();
		System.out.println("**********************************************");

	}
}

把这个判断过程从客户端程序移走

1.6 策略与简单工厂结合

package com.lhx.design.pattern.test;

public class CashContext {

    private CashSuper cs;   //声明一个CashSuper对象

    //通过构造方法,传入具体的收费策略
    public CashContext(int cashType){
        switch(cashType){
            case 1:
                this.cs = new CashNormal();
                break;
            case 2:
                this.cs = new CashRebate(0.8d);
                break;
            case 3:
                this.cs = new CashRebate(0.7d);
                break;
            case 4:
                this.cs = new CashReturn(300d,100d);
                break;
        }
    }

    public double getResult(double price,int num){
        //根据收费策略的不同,获得计算结果
        return this.cs.acceptCash(price,num);
    }    
}
package com.lhx.design.pattern.test;

import java.util.Scanner;

public class Test {

	public static void main(String[] args){

		System.out.println("**********************************************");		
		System.out.println("《大话设计模式》代码样例");
		System.out.println();		

		int discount = 0; 		//商品折扣模式(1.正常收费 2.打八折 3.打七折)
		
		double price = 0d; 		//商品单价
		int num = 0;			//商品购买数量
		double totalPrices = 0d;//当前商品合计费用
		double total = 0d;		//总计所有商品费用
	
		Scanner sc = new Scanner(System.in);

		do {
			System.out.println("请输入商品折扣模式(1.正常收费 2.打八折 3.打七折 4.满300送100):");	
			discount = Integer.parseInt(sc.nextLine());
			System.out.println("请输入商品单价:");	
			price = Double.parseDouble(sc.nextLine());
			System.out.println("请输入商品数量:");	
			num = Integer.parseInt(sc.nextLine());
			System.out.println();	

			if (price>0 && num>0){

				
				//根据用户输入,将对应的策略对象作为参数传入CashContext对象中
				CashContext cc = new CashContext(discount);
				
				//通过Context的getResult方法的调用,可以得到收取费用的结果
				//让具体算法与客户进行了隔离
				totalPrices = cc.getResult(price,num);
				
				total = total + totalPrices;
				
				System.out.println();	
				System.out.println("单价:"+ price + "元 数量:"+ num +" 合计:"+ totalPrices +"元");	
				System.out.println();
				System.out.println("总计:"+ total+"元");	
				System.out.println();
			}
		}
		while(price>0 && num>0);

		System.out.println();
		System.out.println("**********************************************");

	}
}

简单工厂模式我需要客户端认识两个类,CashSuper和CashFacory,而策略模式与简单工厂结合的用法,客户端就只需要认识一个类CashContext就可以了。耦合更加降低。

说得没错,我们在客户端实例化的是CashContext的对象,调用的是CashContext的方GetResult,这使得具体的收费算法彻底地与客户端分离。连算法的父类CashSuper都不让客户端认识了。

1.7 策略模式解析

策略模式封装了变化。还有什么不足吗?

因为在CashContext里还是用到了switch,也就是说,如果我们需要增加一种算法,比如'满200送50',你就必须要更改CashContext中的switch代码,这总还是让人很不爽呀。那你说怎么办,有需求就得改呀,任何需求的变更都是需要成本的,但是成本的高低还是有差异的。高手和菜鸟的区别就是高手可以花同样的代价获得最大的收益或者说做同样的事花最小的代价。面对同样的需求,然是改动越小越好。""你的意思是说,还有更好的办法?""当然。这个办法就是用到了反射Reflect)技术,不过今天就不讲了,以后会再提它的。""反射真有这么神奇?"小菜疑惑地望向了远方。
注:在抽象工厂模式章节有对反射的讲解。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1563592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

坦白局:PMP真的是智商税吗?

近些年报考PMP认证的学员越来越多,PMP全球持证人数已经突破百万了,据PMI统计,IT行业近50%人士都持有PMP证书,因此也有很多学员在思考,PMP持证人员这么多,PMP是不是都已经烂大街了?证书还有含金量…

看完不会来揍我 | R包的下载与安装 | 再也没有一个包可以逃出你的手掌心啦

好久不见!非常抱歉有一段时间没有更新正经内容啦!主要是最近接了一个项目和一个一对一指导,实在是精力有限,又不想随便写几篇应付大家。毕竟,咱们主打高质量嘛!来!大声喊出来! 「要知…

英伟达智算先锋训练,冲刺智算时代实战

随着数字经济的深入发展,智能算力作为关键生产力,其规模在2022年已达到268.0 EFLOPS,并预计到2028年将增长至2769 EFLOPS,显示出强劲的发展势头。在2024年政府工作报告中,也首次提出了“人工智能”行动,强调…

Golang 内存管理和垃圾回收底层原理(二)

一、这篇文章我们来聊聊Golang内存管理和垃圾回收,主要注重基本底层原理讲解,进一步实战待后续文章 垃圾回收,无论是Java 还是 Golang,基本的逻辑都是基于 标记-清理 的, 标记是指标记可能需要回收的对象&#xff0c…

Java设计之道:色即是空,空即是色

0.引子 我们的这个世界上,存在这么一种东西: 第一:它不占据任何3D之体积,即它没有Volume第二:它也不占据任何2D之面积,即它没有Area第三:它也不占据任何1D之长度,即它没有Length 总…

【容易不简单】love 2d Lua 俄罗斯方块超详细教程

源码已经更新在CSDN的码库里: git clone https://gitcode.com/funsion/love2d-game.git 一直在找Lua 能快速便捷实现图形界面的软件,找了一堆,终于发现love2d是小而美的原生lua图形界面实现的方式。 并参考相关教程做了一个更详细的&#x…

【深耕 Python】Data Science with Python 数据科学(7)书352页练习题

写在前面 关于数据科学环境的建立,可以参考我的博客: 【深耕 Python】Data Science with Python 数据科学(1)环境搭建 往期数据科学博文: 【深耕 Python】Data Science with Python 数据科学(2&#xf…

苹果开发者账号注册步骤中的常见疑问解答与技巧分享

转载:注册苹果开发者账号的方法 在2020年以前,注册苹果开发者账号后,就可以生成证书。 但2020年后,因为注册苹果开发者账号需要使用Apple Developer app注册开发者账号,所以需要缴费才能创建ios证书了。 所以新政策出…

算法系列--递归,回溯,剪枝的综合应用(3)

💕"对相爱的人来说,对方的心意,才是最好的房子。"💕 作者:Lvzi 文章主要内容:算法系列–递归,回溯,剪枝的综合应用(3) 大家好,今天为大家带来的是算法系列--递归,回溯,剪枝的综合应用(3),带来几…

深入浅出:大模型产业链的全景解码

大模型产业仿佛如同一场盛宴,虽然AGI的菜肴还没有上桌,但掩盖不住的香味已经让所有人垂涎,都希望自己将来在餐桌上能够“吃饱饱”。这也是一场没有邀请函的宴席,从尚在学校的学生到公司的决策层,都能在生成式AI的相关研…

简单而复杂的Python

Python是一种简单&复杂的编程语言。简单的时候可以到极致: print(hello world!)另一方面,Python 也具有许多复杂的语法特性,例如面向对象编程、装饰器、迭代器、生成器等等。这些特性使得 Python 适用于各种不同的编程任务和项目。 当我…

【JavaWeb】Day31.SpringBootWeb请求响应——分层解耦(二)

3.IOC&DI 3.1 IOC&DI入门 完成Controller层、Service层、Dao层的代码解耦 思路: 1. 删除Controller层、Service层中new对象的代码 2. Service层及Dao层的实现类,交给IOC容器管理 3. 为Controller及Service注入运行时依赖的对象 Controller程序…

HarmonyOS 应用开发之同步任务开发指导 (TaskPool和Worker)

同步任务是指在多个线程之间协调执行的任务,其目的是确保多个任务按照一定的顺序和规则执行,例如使用锁来防止数据竞争。 同步任务的实现需要考虑多个线程之间的协作和同步,以确保数据的正确性和程序的正确执行。 由于TaskPool偏向于单个独…

【Java代码审计】SSTI模板注入篇

【Java代码审计】SSTI模板注入篇 1.概述2.Velocity 模板引擎3.Thymeleaf 模板注入复现普通url作为视图 4.SSTI 漏洞修复白名单控制跳转模版设置response参数 1.概述 模板引擎支持使用静态模板文件,在运行时用 HTML 页面中的实际值替换变量/占位符,从而让…

蓝桥杯刷题第六天(昨天忘记发了)

今天想从不一样的角度来解题:从时间紧张暴力求解到思路阔达直接通过所有案例 暴力方法: 思路第一眼看到这个问题我就想到了第一个思路就是先用两个数组一个存石子数一个存颜色状态,每次遍历一遍看看有没有相邻石子颜色一样且为和最小的。 im…

如何整合当地商家资源?如何进行二次变现?

随着市场竞争的日益激烈,商家们纷纷寻求创新的营销方式来扩大市场份额、提升品牌影响力。异业联盟作为一种新型的商业合作模式,正逐渐受到业界的关注和认可。本文将探讨异业联盟的可行性,并分析其是否可以通过小程序形式实现更广泛的应用。 一…

zip解压异常java.lang.IllegalArgumentException: MALFORMED处理

使用hutool解压zip包时出错: //压缩包解压到固定目录 ZipUtil.unzip(tempZipFile,dir);在解压文件的时候报错,原因是压缩文件中有中文;导致错误,解决办法是设置编码: ZipFile tempZipFile new ZipFile(zipFile, Cha…

h5 笔记1

Internet是InternationalNetwork的缩写,又称“因特网”。它是将全世界数以千计的上网设备通过TCP/IP通信协议连接在一起。Internet上的服务众多,主要的服务有WWW(万维网)、E-Mail(电子邮件)、FTP(FileTransferProtocol,文件传输协议)、Telnet…

Ps:颜色查找

颜色查找 Color Lookup命令通过应用预设的 LUT 来改变图像的色彩和调性,从而为摄影师和设计师提供了一种快速实现复杂色彩调整的方法,广泛应用于颜色分级、视觉风格的统一和创意色彩效果的制作。 Ps菜单:图像/调整/颜色查找 Adjustments/Colo…

微信小程序-文字转语音(播放及暂停)

1、使用微信小程序的同声传译功能 小程序平台-设置-第三方设置-插件管理-新增同声传译插件 小程序app.json文件配置 "plugins": {"WechatSI": {"version": "0.3.5","provider": "wx069ba97219f66d99"}},小程序中…