大话设计模式——02策略模式

该博客介绍了如何在商场收银系统中使用策略模式和简单工厂模式来灵活处理打折和返现策略。通过创建CashSuper抽象类和多个具体的收费策略子类(如正常收费、打折、返现),实现了不同收费算法的封装。简单工厂模式则用于根据输入的类型动态创建并返回相应的收费策略对象,降低了客户端的耦合度。最后,展示了如何结合使用策略模式和简单工厂模式,使客户端只需关注CashContext类,进一步降低了依赖性。
摘要由CSDN通过智能技术生成

一、商场收银软件

营业员根据客户所购商品的单价和数量,向客户收费。用确定按钮来算出每种商品的费用,列表框来记录商品清单,并记录总计金额。

变更1:商场对商品搞活动,所有的商品打八折。

变更2:商场的活动加大,满300元返100元的促销活动。

变更3:所有的商品打五折,同时满300元返100元。

二、简单工厂实现

面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。比如,打一折和打九折只是形式的不同,抽象分析出来,所有的打折算法都是一样的,所以打折算法应该是一个类。

// 现金收费抽象类
// 也是Strategy类,定义所有支持的算法的公共接口
public abstract class CashSuper {

public abstract double acceptCash(double money);

}
//正常收费子类
public class CashNormal extends CashSuper {

@Override
public double acceptCash(double money) {
	return money;
}

}
// 打折收费子类
public class CashRebate extends CashSuper {

private double discount = 1.0d;

public CashRebate(double discount) {
	this.discount = discount;
}

@Override
public double acceptCash(double money) {
	return money * discount;
}

}
// 返利收费子类
public class CashReturn extends CashSuper {

private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;

public CashReturn(double moneyCondition, double moneyReturn) {
	this.moneyCondition = moneyCondition;
	this.moneyReturn = moneyReturn;
}

@Override
public double acceptCash(double money) {
	double result = money;
	if (money >= moneyCondition) {
		result = money - Math.floor(money / moneyCondition) * moneyReturn;
	}
	return result;
}

}
// 现金收费工厂类
public class CashFactory {

public static CashSuper createCashAccept(String type) {
	CashSuper cs = null;
	switch (type) {
	case "正常收费":
		cs = new CashNormal();
		break;
	case "打8折":
		cs = new CashRebate(.8);
		break;
	case "满300返回100":
		cs = new CashReturn(300, 100);
		break;
	default:
		break;
	}
	return cs;
}

}
// 简单工厂模式客户端
public class RunMain {

public static void main(String[] args) {
	double totalPrices = 0.0d;
	double prices = 0.0d;
	
	int number = 10;
	double unitPrice = 80;
	
	CashSuper cashAcceptor = CashFactory.createCashAccept("正常收费");
	// cashAcceptor = CashFactory.createCashAccept("打8折");
	// cashAcceptor = CashFactory.createCashAccept("满300返回100");
	
	prices = cashAcceptor.acceptCash(number * unitPrice);
	totalPrices += prices;
	System.out.println("单价:" + unitPrice + " 数量:" + number + " 合计:" + prices);
	System.out.println("汇总:" + totalPrices);
	
}

}
三、策略模式

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

// Cash上下文,用来维护一个对Strategy对象的引用
public class CashContext {

private CashSuper cs = null;

// 初始化时,传入具体的策略对象
public CashContext(CashSuper cs) {
	this.cs = cs;
}

// 根据具体的策略对象,调用其算法的方法
public double contextInterface(double money){
	return cs.acceptCash(money);
}

}
// 策略模式客户端
public class RunMain {

public static void main(String[] args) {
	double totalPrices = 0.0d;
	double prices = 0.0d;
	
	int number = 10;
	double unitPrice = 80;

	CashContext cc = new CashContext(new CashNormal());
	// cc = new CashContext(new CashRebate(.8));
	// cc = new CashContext( new CashReturn(300, 100));
	
	prices = cc.contextInterface(number * unitPrice);
	totalPrices += prices;

	System.out.println("单价:" + unitPrice + " 数量:" + number + " 合计:" + prices);
	System.out.println("汇总:" + totalPrices);
	
}

}
四、策略与简单工厂模式结合

简单工厂模式需要让客户端认识两个类,CashSuper和CashFactory,而策略与简单工厂模式结合的用法,客户端只需要认识一个类CashContext即可,耦合更低。同时客户端实例化的是CashContext的对象,调用的是CashContext的方法,这使得具体的收费算法彻底地与客户端分离。

// Cash上下文
public class CashContext {

private CashSuper cs = null;

//将实例化具体策略的过程由客户端转移到Context类中,简单工厂模式的应用
public CashContext(String type) {
	switch (type) {
		case "正常收费":
			cs = new CashNormal();
			break;
		case "打8折":
			cs = new CashRebate(.8);
			break;
		case "满300返回100":
			cs = new CashReturn(300, 100);
			break;
		default:
			break;
	}
}

// 根据具体的策略对象,调用其算法的方法
public double contextInterface(double money){
	return cs.acceptCash(money);
}

}
// 策略与简单工厂模式结合客户端
public class RunMain {

public static void main(String[] args) {
	double totalPrices = 0.0d;
	double prices = 0.0d;
	
	int number = 10;
	double unitPrice = 80;

	CashContext context = new CashContext("正常收费");
	// CashContext context = new CashContext("打8折");
	// CashContext context = new CashContext("满300返回100");
	
	prices = context.contextInterface(number * unitPrice);
	totalPrices += prices;
	
	System.out.println("单价:" + unitPrice + " 数量:" + number + " 合计:" + prices);
	System.out.println("汇总:" + totalPrices);
}

}

————————————————
版权声明:本文为CSDN博主「无跬步不千里」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kuibuzhiqianli/article/details/86559433

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值