设计模式学习(一)策略模式

(what)什么是策略模式【定义】?

对算法(策略)进行封装,让调用方能很方便的切换不同的算法(策略)。


(how)怎样使用策略模式【原理】?

直接上代码:

package strategy.example2.strategy;

import java.math.BigDecimal;
/**
 * 
 * @Title CashStrategy.java
 * 
 * @Description: TODO 收费策略
 * 
 * @author heps
 *
 */
public interface CashStrategy {

	/**
	 * 收费方法
	 * @param total 商品金额
	 * @return 优惠后应收金额
	 */
	BigDecimal cash(BigDecimal total);
	
}

package strategy.example2.strategy;

import java.math.BigDecimal;
/**
 * 
 * @Title NormalCash.java
 * 
 * @Description: TODO 普通收费策略
 * 
 * @author heps
 *
 */
public class NormalCash implements CashStrategy{

	@Override
	public BigDecimal cash(BigDecimal total) {
		if(null == total){
			throw new IllegalArgumentException("total can not be null!");
		}
		if(total.compareTo(BigDecimal.ZERO) <=0 ){
			throw new IllegalArgumentException("total can not be negative!");
		}
		return total;
	}

}

package strategy.example2.strategy;

import java.math.BigDecimal;
/**
 * 
 * @Title SaleAmountCash.java
 * 
 * @Description: TODO 满多少减多少收费策略
 * 
 * @author heps
 *
 */
public class SaleAmountCash implements CashStrategy{

	/**打折金额,减多少**/
	private BigDecimal discountAmount = new BigDecimal("100");
	/**条件金额,满多少**/
	private BigDecimal conditionAmount = new BigDecimal("1000");
	
	public BigDecimal getDiscountAmount() {
		return discountAmount;
	}

	public void setDiscountAmount(BigDecimal discountAmount) {
		if(null == discountAmount){
			throw new IllegalArgumentException("discountAmount can not be null!");
		}
		if(discountAmount.compareTo(BigDecimal.ZERO) <=0 ){
			throw new IllegalArgumentException("discountAmount can not be negative!");
		}
		this.discountAmount = discountAmount;
	}

	public BigDecimal getConditionAmount() {
		return conditionAmount;
	}

	public void setConditionAmount(BigDecimal conditionAmount) {
		if(null == conditionAmount){
			throw new IllegalArgumentException("conditionAmount can not be null!");
		}
		if(conditionAmount.compareTo(BigDecimal.ZERO) <=0 ){
			throw new IllegalArgumentException("conditionAmount can not be negative!");
		}
		this.conditionAmount = conditionAmount;
	}

	@Override
	public BigDecimal cash(BigDecimal total) {
		if(null == total){
			throw new IllegalArgumentException("total can not be null!");
		}
		if(total.compareTo(BigDecimal.ZERO) <=0 ){
			throw new IllegalArgumentException("total can not be negative!");
		}
		BigDecimal cash = total;
		if(total.compareTo(conditionAmount) >= 0){
			cash = cash.subtract(discountAmount);
		}
		return cash;
	}

}

package strategy.example2.strategy;

import java.math.BigDecimal;
/**
 * 
 * @Title SalePercentCash.java
 * 
 * @Description: TODO 折扣收费策略
 * 
 * @author heps
 *
 */
public class SalePercentCash implements CashStrategy{

	/**打几折小数**/
	private double percent = 0.95;
	
	
	public double getPercent() {
		return percent;
	}


	public void setPercent(double percent) {
		if(0 >= percent || 1 <= percent){
			throw new IllegalArgumentException("percent must between 0 and 1!");
		}
		this.percent = percent;
	}


	@Override
	public BigDecimal cash(BigDecimal total) {
		if(null == total){
			throw new IllegalArgumentException("total can not be null!");
		}
		if(total.compareTo(BigDecimal.ZERO) <=0 ){
			throw new IllegalArgumentException("total can not be negative!");
		}
		return total.multiply(new BigDecimal(percent+""));
	}

}

package strategy.example2.context;

import java.math.BigDecimal;

import strategy.example2.strategy.CashStrategy;
/**
 * 
 * @Title Cashier.java
 * 
 * @Description: TODO 收银员
 * 
 * @author heps
 *
 */
public class Cashier {

	/**收费策略**/
	private CashStrategy cashStrategy;
	
	public CashStrategy getCashStrategy() {
		return cashStrategy;
	}

	public void setCashStrategy(CashStrategy cashStrategy) {
		this.cashStrategy = cashStrategy;
	}

	/**
	 * 收费方法
	 * @param total 商品总价
	 * @return 优惠后应收金额
	 */
	public BigDecimal cash(BigDecimal total){
		return cashStrategy.cash(total);
	}
}

package strategy.example2;

import java.math.BigDecimal;

import strategy.example2.context.Cashier;
import strategy.example2.strategy.SaleAmountCash;
import strategy.example2.strategy.SalePercentCash;

public class Test {

	public static void main(String[] args) {
		BigDecimal total = new BigDecimal("1000");
		BigDecimal cash = null;
		Cashier cashier = new Cashier();
		cashier.setCashStrategy(new SaleAmountCash());
		cash = cashier.cash(total);
		System.out.println(new StringBuffer("total:").append(total).append(",need to pay:").append(cash));
		cashier.setCashStrategy(new SalePercentCash());
		cash = cashier.cash(total);
		System.out.println(new StringBuffer("total:").append(total).append(",need to pay:").append(cash));
	}
}


【总结】



(when)什么时候使用【场景】?

当需求中需要给同一对象(客户/产品)制定一系列的规则(算法/策略)时,可以将这些同一纬度的规则单独封装起来,并聚合到调用者(上下文)内部来进行调用。


(why)为什么要用策略模式【设计原则】?

1.  Identify the aspects of your application that vary and separate them from what stays the same.
 * (找到系统中变化的部分,将变化的部分同其它稳定的部分隔开。变化的部分隔离成接口,聚合到需要的程序里)【扩展性好】
 2.  Program to an interface, not an implementation.
 * (面向接口编程,而不要面向实现编程。通过聚合、实现接口等方式)【灵活性好】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值