设计模式之策略模式

策略模式(Strategy):Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类.

,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户


Strategy的结构图 


下面用一个例子来说明策略模式(模拟商场的收费系统):

首先创建一个现金收费的抽象类

/**
 *现金收费的抽象类,接收参数为商品原价
 * @author thinkpad
 *
 */
public abstract class BaseCash {
	public abstract Double acceptCash(double money);
}

再创建3个不同的模式来计算消费(继承现金收费类):

/**
 * 正常收费类,继承BaseCash
 * @author thinkpad
 *
 */
class Normal extends BaseCash {

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

}

/**
 * 打折收费类,继承BaseCash
 * @author thinkpad
 *
 */
class Discount extends BaseCash {
	private Double dis = 0D;
	/*
	 * 利用构造方法初始化折扣
	 */
	public Discount(String dis) {
		this.dis = Double.valueOf(dis);
	}
	@Override
	public Double acceptCash(double money) {
		return money*dis;
	}
}

/**
 * 返利收费类,继承BaseCash
 * @author thinkpad
 *
 */
class ReturnMoney extends BaseCash {
	private double moneyCondition = 0d;
	private double moneyReturn = 0d;
	public ReturnMoney(double moneyCondition,double moneyReturn) {
		this.moneyCondition = moneyCondition;
		this.moneyReturn = moneyReturn;
	}
	@Override
	public Double acceptCash(double money) {
		double count = 0d;
		if(money>=moneyCondition){
			count = Math.floor(money/moneyCondition);
			return money-moneyReturn*count;
		}
		return money;
	}
创建一个CashContext类,用来维护对BaseCash对象的引用:

/**
 * CashContext类,用来维护对BaseCash对象的引用
 * @author thinkpad
 *
 */
public class CashContext {
	
	private BaseCash bc;
	
	public CashContext(BaseCash baseCash) {
		this.bc = baseCash;
	}
	
	/**
	 * 根据不同的收费对象计算实际金额
	 * @param money
	 * @return
	 */
	public double getResult(double money){
		return bc.acceptCash(money);
	}
}
建立一个测试类:

Scanner input = new Scanner(System.in);
		CashContext cc = null;
		String ans = null;
		double totalPrice = 0d;
		double total = 0d;
		System.out.println("请选择优惠操作,1为正常收费;2为打8折;3为满300,返100");
		int action = input.nextInt();
		//根据选择的操作,将相应的策略对象传入CashContext的对象中
		if(action==1){   
			cc = new CashContext( new Normal());
		}else if(action==2){
			cc = new CashContext(new Discount("0.8"));
		}else if(action==3){
			cc = new CashContext(new ReturnMoney(300,100));
		}
		do {
			System.out.println("请输入单价");
			Double price = input.nextDouble();
			System.out.println("请输入数量");
			int number = input.nextInt();
			totalPrice = cc.getResult(price*number);//通过CashContext的getResult()的调用,可以得到收取费用的结果,让具体的算法与客户进行了隔离
			total+=totalPrice;
			System.out.println("是否继续添加商品Y/N");
			ans = input.next();
		} while (ans.equalsIgnoreCase("Y"));
		System.out.println("付款金额为:"+total);
	}

通过以上例子完成了策略模式的使用,重点是BaseCash抽象类和CashContext类。

以上只使用了策略模式完成功能,把判断算法的工作丢在了客户端,

下面我们简单工厂模式和策略模式结合起来完成上面的例子:

把CashContext类中代码改成下面所示:把之前的传入策略对象改成了传入判断策略的变量

/**
 * CashContext类,用来维护对BaseCash对象的引用
 * @author thinkpad
 *
 */
public class CashContext {
	
	private BaseCash bc;
	
	public CashContext(int action) {    //此时参数不是策略对象,而是一个表示收费类型的变量
		if(action==1){   
			bc =  new Normal();         //将实例化具体策略的过程由客户端转移到CashContext中,这是简单工厂的应用
		}else if(action==2){
			bc = new Discount("0.8");
		}else if(action==3){
			bc = new ReturnMoney(300,100);
		}
	}
	
	/**
	 * 根据不同的收费对象计算实际金额
	 * @param money
	 * @return
	 */
	public double getResult(double money){
		return bc.acceptCash(money);
	}
}

改动后的测试代码如下:

Scanner input = new Scanner(System.in);
		String ans = null;
		double totalPrice = 0d;
		double total = 0d;
		System.out.println("请选择优惠操作,1为正常收费;2为打8折;3为满300,返100");
		int action = input.nextInt();
		CashContext cc = new CashContext(action);//此时参数不是策略对象,而是一个表示收费类型的变量
		do {
			System.out.println("请输入单价");
			Double price = input.nextDouble();
			System.out.println("请输入数量");
			int number = input.nextInt();
			totalPrice = cc.getResult(price*number);//通过CashContext的getResult()的调用,可以得到收取费用的结果,让具体的算法与客户进行了隔离
			total+=totalPrice;
			System.out.println("是否继续添加商品Y/N");
			ans = input.next();
		} while (ans.equalsIgnoreCase("Y"));
		System.out.println("付款金额为:"+total);
	}

通过简单工厂和策略两种模式的结合使用,把判断算法的工作也从客户端分离开了




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值