策略模式介绍:
在软件开发中经常会遇到这样的情况:实现某一个功能可以有多种算法或者策略,我们根据实际情况选择不同的算法或者策略来完成该功能。
针对这种情况,一种常规的做法是将多个算法或者策略写到一个类中,每一个方法对应一种算法或者策略,当然也可以将这些算法或者策略封装到一个方法中,对if else 或者 case 等条件判断语句来选择具体的算法。这两种实现方法我们都可以称为硬编码,然而,当很多个算法集中到一个类中时,这个类就变得非常臃肿,这个类的维护成本也会加大,如果有新的算法了,必须得修改类的源代码才可以,这就违反了上面所说的对修改关闭对扩展开放的原则了。
如果将这些算法抽象出来,提供一个统一的接口, 不同的算法或者策略有不同的实现类,这样在程序客户端就可以通过注入不同的实现对象来实现动态的算法的替换,这种模式的可扩展性,可难搞性也就更高,也就是本章所说策略模式
定义
策略模式定义了一系列的算法,将每一个算法封装起来,而且使它们还可以互换,策略模式让算法独立于使用它的客户而独立的变化
我们以生活中的例子来举例,比如商场打折的情况:
一件100元的商品
1 对于普通会员,不打折,100元
2 对于白金会员,打9折,只需要90元
3 对于黄金会员,打8折,只需要80元
代码如下:
/**
* 计算商品价格的接口,也就是算法的接口
*/
public interface ICalcPrice {
double calcPrice(double price);
}
/**
* 普通会员不打折
*/
public class NormalMember implements ICalcPrice{
@Override
public double calcPrice(double price) {
return price;
}
}
/**
* 白金会员打9折
*/
public class WhiteGoldMember implements ICalcPrice{
@Override
public double calcPrice(double price) {
return 0.9 * price;
}
}
/**
* 黄金会员打8折
*/
public class YellowGoldMember implements ICalcPrice{
@Override
public double calcPrice(double price) {
return 0.8 * price;
}
}
/**
* 商场
*/
public class Shop {
ICalcPrice strategy;
//设置不同的策略
public void setStrategy(ICalcPrice strategy){
this.strategy = strategy;
}
//计算价格
public double calcPrice(double price){
return strategy.calcPrice(price);
}
}
测试代码如下:
/**
* 策略模式
*/
public class StrategyTest {
public static void main(String[] args){
test();
}
public static void test() {
Shop shop = new Shop();
NormalMember normalMember = new NormalMember();
WhiteGoldMember whiteGoldMember = new WhiteGoldMember();
YellowGoldMember yellowGoldMember = new YellowGoldMember();
//一本书100块钱
double price = 100;
shop.setStrategy(normalMember);
System.out.println("我是普通会员,我不打折,价格为:" + shop.calcPrice(price));
shop.setStrategy(whiteGoldMember);
System.out.println("我是白金会员,我打9折,价格为:" + shop.calcPrice(price));
shop.setStrategy(yellowGoldMember);
System.out.println("我是黄金会员,我打8折,价格为:" + shop.calcPrice(price));
}
}
策略模式很好的运用了面向对象接口,主要依赖面向对象的继承和多态,把策略封装成接口,子类实现,所有基类出现的地方,都可以替换为子类的对象,就是里氏替换原则。