1,概念
定义了一系列算法,并将每个算法封装起来,让它们之间可以互相替换,让算法的变化独立于使用算法的客户端。(封装变化)
是硬编码(Hard Coding)的替换。如查找、排序等,硬编码是在一个类中,提供多个方法,每一个方法对应一个具体的查找算法。如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码复杂,维护困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
1)举例
vip打折,每个等级的vip他的打折力度不一样。
2)对比
与工厂模式的对比:工厂封装对象,策略是封装算法
策略模式解决的是客户端选择方法的封装方法(与之相比的是简单工厂模式封装的是对象),其实把简单工厂模式稍作修改,就是策略模式了。
可以认为是用简单工厂模式返回了一系列有共同父类或者同一接口的对象,然后调用对象的接口或者虚方法。这样客户端代码只是通过工厂生成了一个对象,然后调用对象的方法,并通过多态来实现不同的程序功能。
2,场景
①许多相关的类仅仅是行为有异。
“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
② 需要使用一个算法的不同变体。
③算法使用客户不应该知道的数据。
④一个类定义了多种行为 , 这些行为以多个条件语句的形式出现。
例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
3,类图
策略模式中不同的策略创建可以采用工厂模式,一般策略模式可能和工厂模式结合使用。
1)策略(Strategy)
策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法。
2)具体策略(ConcreteStrategy)
具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。
3)上下文(Context)
上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。
4,优缺点
优点:
- 让算法的变化独立于使用算法的客户。(封装变化)
- 扩展性良好。(开闭原则)
缺点:
1.策略类会增多,每一种策略就是一个类。
2.所有策略类都需要对外暴露,客户端需要了解所有的策略类。
5,demo
package strategy;
public class Main {
public static void main(String[] args){
/*乘坐火车旅行*/
PersonContext person = new PersonContext(new TrainStrategy());
System.out.println( person.travel() );
/*乘飞机*/
person.setTravelStrategy(new AirPlanelStrategy());
System.out.println( person.travel() );
}
}
package strategy;
public class PersonContext {
private TravelStrategy strategy= null;
public PersonContext(TravelStrategy strategy){
this.strategy = strategy;
}
/**
* 旅行
*/
public void setTravelStrategy(TravelStrategy strategy){
this.strategy = strategy;
}
public String travel(){
return this.strategy.travelAlgorithm();
}
}
package strategy;
/**
* 抽象策略类(Strategy):定义所有支持的算法的公共接口。
* Context使用这个接口来调用某ConcreteStrategy定义的算法。
* @author luo
*
*/
public interface TravelStrategy {
public String travelAlgorithm();
}
package strategy;
/**
* 具体策略类。实现Strategy接口。
* @author luo
*
*/
public class AirPlanelStrategy implements TravelStrategy{
@Override
public String travelAlgorithm(){
return "AirPlanelStrategy";
}
}
package strategy;
/**
* 具体策略类,实现Strategy接口
* @author luo
*
*/
public class TrainStrategy implements TravelStrategy{
@Override
public String travelAlgorithm(){
return "TrainStrategy";
}
}