• 有趣的设计模式——解救抓狂的商场收银员



    版权声明

    • 本文原创作者:谷哥的小弟
    • 作者博客地址:http://blog.csdn.net/lfdfhl

    场景与问题

    商场中经常搞各种促销活动;例如:满200返50,打9折,会员8.8折,冲100送20等等。这些商业活动的背后商品价格的计算方式各不相同,种类繁复;着实让商场的收银员头痛不已。

    为了应对类似的情况,我们的程序中或许要写很多的if…else进行分支判断造成代码臃肿、难以维护。此时,我们可用策略模式解救抓狂的商场收银员。

    策略模式概述

    在此,概述策略模式。

    策略模式定义

    Strategy Pattern:Define a family of algorithms,encapsulate each one and make them interchangeable.Strategy lets the algorithmvary independently from clients that use it。

    策略模式:定义一系列的算法,把它们一个个封装起来,并且使他们可相互替换。本模式使得算法的变化可以独立于使用它的客户。

    策略模式角色

    在此,介绍策略模式中的主要角色。

    Context 封装角色

    Context也叫做上下文角色,它 起承上启下封装作用;用于屏蔽高层模块对策略、 算法的直接访问,封装可能存在的变化。

    Strategy 抽象策略角色

    策略或算法家族的抽象, 它通常被定义为接口或抽象类。该接口或抽象类中定义每个策略或算法必须具有的方法和属性。

    ConcreteStrategy 具体策略角色

    实现抽象策略中的操作。

    策略模式案例

    在此,以案例形式讲解策略模式。

    CashStrategy

    CashStrategy为抽象类,代码如下:

    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public abstract class CashStrategy {
    	
    	public abstract double receiveCash(double money);
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    CashNormal

    CashNormal类继承自CashStrategy;用于表示正常收费业务,代码如下:

    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public class CashNormal extends CashStrategy{
    	 
    	@Override
    	public double receiveCash(double money) {
    		return money;
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    CashDiscount

    CashDiscount类继承自CashStrategy;用于表示打折收费业务,代码如下:

    package com.strategy01;
    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public class CashDiscount extends CashStrategy{
    	private double discount=0;
    	
    	public CashDiscount(double discount) {
    		this.discount = discount;
    	}
     
    	@Override
    	public double receiveCash(double money) {
    		return money*discount;
    	}
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    CashReturn

    CashReturn类继承自CashStrategy;用于表示返现收费业务,代码如下:

    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public class CashReturn extends CashStrategy{
    	 
    	private double moneyThreshold;
    	private double moneyReturn;
    	
    	public CashReturn(double moneyRaw, double moneyReturn) {
    		this.moneyThreshold = moneyRaw;
    		this.moneyReturn = moneyReturn;
    	}
     
    	@Override
    	public double receiveCash(double money) {
    		double result=money;
    		if(money>moneyThreshold) {
    			result = money - moneyReturn;
    		}
    		return result;
    	}
     
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    CashContext

    CashContext用于表示上下文,代码如下:

    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public class CashContext {
    	private CashStrategy cashStrategy;
     
    	public CashContext(CashStrategy cashStrategy) {
    		this.cashStrategy = cashStrategy;
    	}
    	
    	public double charge(double money) {
    		return cashStrategy.receiveCash(money);
    	}
     
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    Test

    Test类为测试类,代码如下:

    import java.util.Scanner;
    /**
     * 本文作者:谷哥的小弟 
     * 博客地址:http://blog.csdn.net/lfdfhl
     */
    public class Test {
    	public static void main(String[] args) {
    		Scanner scannner = new Scanner(System.in);
    		System.out.println("输入收费模式:");
    		String content = scannner.next();
    		CashContext cashContext = null;
    		switch (content) {
    			case "正常收费":
    				CashNormal cashNormal = new CashNormal();
    				cashContext = new CashContext(cashNormal);
    				break;
    			case "满200返50":
    				CashReturn cashReturn = new CashReturn(200, 50);
    				cashContext = new CashContext(cashReturn);
    				break;
    			case "打9折":
    				CashDiscount cashDiscount = new CashDiscount(0.9);
    				cashContext = new CashContext(cashDiscount);
    				break;
    			default:
    				System.out.println("信息有误,请重新输入");
    				break;
    		}
    		System.out.println("输入消费金额:");
    		double money = scannner.nextInt();
    		double result = cashContext.charge(money);
    		System.out.println("最终实际消费:" + result);
    		scannner.close();
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述

    测试结果

    在这里插入图片描述

  • 相关阅读:
    mysql数据库:DCL:管理用户,授权
    java毕业设计点播影院运营系统mybatis+源码+调试部署+系统+数据库+lw
    职场:“工作”的理解
    GeoPandas和Matplotlib地图高亮显示——与中国建交的国家(不全)
    el-input中监听键盘事件“回车”和“Tab”
    iLogtail 社区版使用入门 - 采集 MySQL Binlog
    Spring概述
    基于Android的乐鲜生活APP设计与实现
    2023-09-12 创业手册-记录
    Excel也能调用HFSS?
  • 原文地址:https://blog.csdn.net/lfdfhl/article/details/126273869