设计模式-策略模式(STRATEGY)以及JDK类库中的应用

策略模式的定义:定义一系列的算法,将他们一个个的封装起来,并是他们可以相互替换,让算法独立于客户端而独立变化。

UML类图:在这个类图包含三个类别:①抽象策略类:通常由接口或抽象类实现,定义所有支持算法的公共接口。②具体策略类:实现抽象策略类,在重写方法中写入算法或行为。③环境类(上下文):决定用哪一个具体抽象类的算法。

案例:商场收银系统

输入商品单价和数量,返回总金额,当商场加入打折、满减活动时,系统执行不同的算法,但是相同的都是输入单价和数量,返回总金额,所以可以在抽象类或接口中写一个公共方法。

抽象策略类:

public interface CalPriceSuper {

	public double calPrice(double money);
	
}

具体策略类:①正常收费。②打折。③满减

/**
 *	正常收费
 */
public class NormalPrice implements CalPriceSuper{

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

}
/** 
 *	打折
 */
public class DiscountPrice implements CalPriceSuper{

	public double discount;
	
	public DiscountPrice(double discount) {
		this.discount = discount;
	}
	
	@Override
	public double calPrice(double money) {
		return money * discount;
	}

}
/**
 *	满减
 */
public class PlusPirce implements CalPriceSuper{

	public double mPrice;
	
	public double jPrice;
	
	public PlusPirce(double mPrice, double jPrice) {
		super();
		this.mPrice = mPrice;
		this.jPrice = jPrice;
	}

	@Override
	public double calPrice(double money) {
		if(money >= mPrice){
			return money-(money/mPrice)*jPrice;
		}
		return money;
	}

}

上下文(环境)类:

/**	
 *	上下文:决定用哪一个具体实现类,将具体实现类与客户隔离
 */
public class CashContext {

	CalPriceSuper calPriceSuper;
	
	public CashContext(CalPriceSuper calPriceSuper){
		this.calPriceSuper = calPriceSuper;
	}
	
	public double getResult(double money){
		return calPriceSuper.calPrice(money);
	}
}

客户端调用方法:在客户端判断使用哪一个算法。

/**
* 	客户端调用策略类方法
*/
public static void main(String[] args) {
	CashContext context = new CashContext(new DiscountPrice(0.6));
	double result = context.getResult(100.0);
}

策略类和简单工厂的融合

/**	
 *	借鉴简单工厂的思想,在上下文中,通过传入类型来创建具体策略类
 */
public class CashContext {

	CalPriceSuper calPriceSuper;
	
	public CashContext(String type){
		if("正常收费".equals(type)){
			this.calPriceSuper = new NormalPrice();
		}else if("0.6折".equals(type)){
			this.calPriceSuper = new DiscountPrice(0.6);
		}else if("满300减150".equals(type)){
			this.calPriceSuper = new PlusPirce(300.0, 150.0);
		}else if("满100得10点积分".equals(type)){
			this.calPriceSuper = new PlusPirce(100, 10);
		}
	}
	
	public double getResult(double money){
		return calPriceSuper.calPrice(money);
	}
	
}

客户端调用方法:将具体策略类与客户完全隔离,只需要用到CashContext类就可以实现,耦合度降低。

/**
* 	客户端调用策略类方法
*/
public static void main(String[] args) {
	CashContext context = new CashContext("0.6折");
	double result = context.getResult(100.0);
}

策略模式的优点

 

①可以随意切换算法。②减少算法类和使用算法类之间的耦合度。③简化单元测试。④可扩展

 

策略模式的缺点

①在context对象中还是会有if-else或switch-case判断,如果需要修改策略类的type,每次都需要修改type代码。②客户端必须知道所有的策略类并需要判断用哪个策略类(简单工厂模式可以解决此问题)。③每个策略类都单独封装成类,策略类数量太多。

抽象工厂模式可以解决switch或if判断的问题。

JDK类库中的策略模式

java.util.Comparator#compare(T o1,T o2)

传递传入不同的参数可以实现不同的算法:

		Comparator<Integer> comparator = new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o1>o2?1:o1==o2?0:-1;
			}
		};
		System.out.println(comparator.compare(2, 1));

javax.servlet.http.HttpServlet

HttpServlet中的doGet、doPost、service方法都可以通过传递不同的request和response来实现不同的业务逻辑。

javax.servlet.Filter#doFilter

Filter可以通过传递request、response、chain来实现不同的业务逻辑。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值