1.策略模式的定义
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面是UML图:
这个模式涉及到三个角色:
1.环境(Context)角色:持有一个Strategy的引用。
2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
下面举一个图书馆对图书进行打折的例子:
行为1:普通成员打九折;
行为2:vip打八折;
行为3:高级vip打七折;
首先把策略的方式抽象出来,如图代码:
public interface LibraryStategy {
/**
* 图书馆对图书对会有进行打折
* 普通成员打9折
* vip打8折
* 高级vip打7折
*/
public double saleBook(double price);
}
其次,把具体的行为具体到每个类中,实现抽象策略。使其成为具体的策略,这就符合定义中将每一个算法封装到具有共同接口的独立的类中,代码如下:
//普通成员
public class Ordinarymembers implements LibraryStategy{
@Override
public double saleBook(double price) {
return price*0.9;
}
}
//会员
public class Member implements LibraryStategy{
@Override
public double saleBook(double price) {
return price*0.8;
}
}
//高级会员
public class Seniormember implements LibraryStategy{
@Override
public double saleBook(double price) {
return price*0.7;
}
}
最后,创建一个环境角色:价格,并且引用一个策略。代码如下:
public class Price {
private LibraryStategy stategy;
public Price(LibraryStategy ls){
this.stategy = ls;
}
/**
* 对图书进行大者
* @param price图书的原价
* @return
*/
public double quote(double price){
return stategy.saleBook(price);
}
}
测试类,只写了一个,如下:
public class StategyTest {
public static void main(String[] args) {
//创建策略使用的对象
LibraryStategy ls = new Member();
//创建环境
Price price = new Price(ls);
//计算价格
System.out.println(price.quote(50));
}
}
从上述的例子可一个看出,将每一个算法封装到具有共同接口的独立的类中,具体选用哪一个算法和行为是由客户端决定的。
2.策略模式的有点和缺点
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
3.总结
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
上述只是一些简单的实现,想研究的更深一点,还需要继续学习。