设计模式学习笔记——策略模式

策略模式

问题:商场收银软件,根据单价和数量,得到总价。
设计思路:两个输入框,分别代表单价和数量,一个下拉框,选项有:正常,打折,满减等算法
商场有时需要正常收费,有时打折扣,有时满300送100.下面是简单工厂模式下:

所有算法的父类抽象类CashSuper:
public abstract class CashSuper {

	public abstract double acceptCash(double money);
	
}
其下的其他子类,分别代表不同的收费方式
/**
 * @author xukai 打折收费
 */
public class CashRebate extends CashSuper {

	private double moneyRebate = 1d;

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

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

}
/**
 * @author xukai 正常收费
 */
public class CashNormal extends CashSuper {

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

}
/**
 * @author xukai
 * 满减收费
 */
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 "打八折":
			cs = new CashRebate(0.8);
			break;
		case "满300减100":
			cs = new CashReturn(300.0, 100.0);
			break;
		}
		return cs;
	}

}
使用简单工厂模式解决的是对象的创建问题,工厂包括了所有的收费方式,商场更改打折额度和返利额度非常频繁,那么就要经常扩展收费方式,从而修改工厂,需要引进新的设计模式来解决这一问题。
策略模式定义:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。

策略模式的实现:
相比简单工厂模式,去掉了包含静态方法的工厂类,添加了CashContext收费上下文类:
public class CashContext {

	private CashSuper cs;

	public CashContext(CashSuper cs) {
		this.cs = cs;
	}

	public double getResult(double money) {
		return cs.acceptCash(money);
	}

}
通过CashContext进行调用,假如,需要添加一个打七折的收费方式,只需要重新写一个CashRebate为0.7的类,不用改CashContext中的实现。
测试方法:
	public void btn_submit(double price,double count,String type){
		CashContext cc = null;
		switch (type) {
		case "正常收费":
			cc = new CashContext(new CashNormal());
			break;
		case "打八折":
			cc = new CashContext(new CashRebate(0.8));
			break;
		case "满300减100":
			cc = new CashContext(new CashReturn(300.0, 100.0));
			break;
		}
		System.out.println("总费为:" + cc.getResult(price*count));
	}
这种办法相当于把收费方式由客户端进行判断使用哪个算法。

简单工厂模式和策略模式对比

1.前者在内部创建需要的对象,后者对象已经创建完毕,只是调用不同的实现方法。
2.前者进入工厂之前是不存在的,返回的是要使用的对象。后者进入之前是该对象,返回依然是该对象。
3.前者生成算法的判断由工厂决定,后者由客户端决定。
4.前者的客户端需要识别所有算法的父类CashSuper和工厂CashFactory,后者只需要识别CashContext。

简单工厂模式和策略模式结合

将对象的创建转移到CashContext中,客户端不要判断生成那个对象。
public class CashContext {

	private CashSuper cs = null;

	public CashContext(String type) {
		switch (type) {
		case "正常收费":
			cs = new CashNormal();
			break;
		case "满300返100":
			cs = new CashReturn("300", "100");
			break;

		case "打八折":
			cs = new CashRebate("0.8");
			break;

		}
	}

	public double getResult(double money) {
		return cs.acceptCash(money);
	}

}
测试:
public class StrategyTest {

	public static void main(String[] args) {

		CashContext cc = new CashContext("打八折");
		System.out.println(cc.getResult(1000));

		cc = new CashContext("满300返100");
		System.out.println(cc.getResult(1000));

	}

}
这种结合还是有弊端,新增其他算法,必须修改CashContext的switch分支。

策略模式解析

策略模式是一种定义一系列算法的方法,从概念上来将,这些算法完成的都是相同的工作,只是实现不同。
定义算法家族,分别封装起来,让它们之间可以相互转换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
*使用场景:只要在分析过程中听到需要在不同时间应用不同的业务规则,可以考虑使用策略模式处理这种变化的可能性,用来封装算法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值