策略模式属于对象的行为模式,其用意是针对一组算法,将每一个算法封装到具有共同接口的类中,从而使得它们可以相互替换,策略模式使得算法在不影响客户端的情况下发生变化。
策略模式的结构
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,策略模式通常把一个系列的算法包装到一系列的策略类中,作为一个抽象策略类的子类,一句话形容,准备一组算法,并将每一组算法封装起来,使得他们可以互换,
结构图:
此模式涉及到三个角色
环境角色:持有抽象策略角色引用
抽象策略角色:这是一个抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口
具体策略角色:包装了相关算法或行为
认识策略模式
策略模式的重心:策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性
算法的平等性:策略模式的一个很大特点就是各个策略算法的平等性,对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换,所有的策略算法在实现上是相互独立的,相互之间没有依赖的。
策略算法是相同行为的不同实现。
运行时策略的唯一性:
运行期间,策略模式在每一个时刻只能使用一个具体的策略对象,虽然可以在不同的策略实现中切换,但同时只能适用一个。
公有的行为:
常见的是,所有的具体策略类有一些公有的行为,这时应当把这些公有的行为放到共有的抽象类中,当然此时抽象角色类只能使用抽象类而不能使用接口。
策略模式的优点:
1、
策略模式提供了管理相关的算法族 的办法,策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到父类中,从而避免代码重复。
2、使用策略模式可以避免使用多重条件(if else)语句,多重条件语句不利于维护,它把采取哪种算法或采取哪种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句中,比使用继承的方法还要落后。
策略模式的缺点
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这就意味着客户端必须理解这些算法的区别,以便实时选择恰当的算法类,换言之,策略模式只适用于客户端知道算法或行为情况。
2、由于策略模式把每个具体的策略实现都单独封装成类,如果备选的策略很多,那么对象的数据将会很庞大。
public interface Strategy {
public int calculate(int a,int b);
}
public class AddStrategy implements Strategy{
@Override
public int calculate(int a, int b) {
return a+b;
}
}
public class SubtractStrategy implements Strategy{
@Override
public int calculate(int a, int b) {
return a-b;
}
}
public class Environment {
private Strategy strategy;
public Environment(Strategy strategy){
this.strategy = strategy;
}
public void setStrategy(Strategy strategy){
this.strategy = strategy;
}
public Strategy getStrategy(){
return strategy;
}
public int calculate(int a,int b){
return strategy.calculate(a, b);
}
}
public class Client {
public static void main(String[] args) {
Strategy add = new AddStrategy();
Strategy sub = new SubtractStrategy();
Environment environment = new Environment(add);
int addResu = environment.calculate(1, 23);
environment.setStrategy(sub);
int subResu = environment.calculate(2, 6);
System.out.println(addResu +" "+subResu);
}
}