策略模式:策略模式属于对象的行为模式。
其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
策略模式使得算法可以在不影响到客户端的情况下发生变化。
策略模式的三个角色:
环境(Context)角色:持有一个Strategy的引用。
抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
类图如下:
例子如下:
村里的养牛场向村民提供福利,要向外销售鲜奶,
如果是团购享受批发价八折,如果是零售,不享受打折优惠,
现在就是要包装价格的计算方法,分为零售价格与批发价格两种计算方式
/**
* 环境角色类
* 养牛场出售瓶装鲜奶
* 零售(SellRetail)不打折
* 批发(WholeSale) 打八折
* @author wang
*/
public class Discount {
//持有一个具体策略对象
private SalesLevel salesLevel;
/**
* 构造函数 传入一个具体策略对象
* @param salesLevel
*/
public Discount(SalesLevel salesLevel){
this.salesLevel = salesLevel;
}
/**
* 计算鲜奶打折后的价格
* @param price 鲜奶的原价
* @return 打折的价格
*/
public double calculatePrice(double price){
return this.salesLevel.calculatePrice(price);
}
}
/**
* 抽象策略类
* @author wang
*/
public interface SalesLevel {
/**
* 策略方法
* @param price
* @return
*/
public double calculatePrice(double price);
}
/**
* 具体策略类
* 零售价格,不打折
* @author wang
*/
public class SellRetail implements SalesLevel {
public double calculatePrice(double price) {
return price;
}
}
/**
* 具体策略类
* 批发价格 八折
* @author wang
*/
public class WholeSale implements SalesLevel{
public double calculatePrice(double price){
return price * 0.8;
}
}
public class Client {
public static void main(String[] args){
//零售
//选择并创建要使用的策略类对象
SalesLevel salesLevel = new SellRetail();
//创建环境
Discount price = new Discount(salesLevel);
//计算价格
double discount = price.calculatePrice(10);
System.out.println("零售的折前价格:10元,折后价格:"+discount);
//批发
//选择并创建要使用的策略类对象
SalesLevel wholeSalesLevel = new WholeSale();
//创建环境
Discount wholePrice = new Discount(wholeSalesLevel);
//计算价格
double wholeDiscount = wholePrice.calculatePrice(100);
System.out.println("批发的折前价格:100元,折后价格:"+wholeDiscount);
}
}
运行结果如下:
但很重要的一点是,策略模式只支持一个维度的变化,如果新增加一种平行维度计算方式,那可以随时插入即可,比如大批量采购超过500瓶了,可以给于比批发更便宜的价格,
但是要加入酸奶这种产品,然后也要采用批发零售这样的折扣方式,此时的策略模式就不会适用了。