1.针对一组算法,将所有算法封装到具有共同接口的独立类中,使他们可以相互替换
2.示例
抽象的策略接口
public interface Strategy
{
public void useStrategy();
}
实现接口的两种具体策略
public class StrategyA implements Strategy
{
public void useStrategy()
{
System.out.println("StrategyA.useStrategy()");
}
}
public class StrategyB implements Strategy
{
public void useStrategy()
{
System.out.println("StrategyB.useStrategy()");
}
}
某个类持有策略的引用:
public class Context
{
private Strategy strategy;
public Context(Strategy strategy)
{
this.strategy = strategy;
}
public void strategyMethod()
{
strategy.useStrategy();
}
}
调用这个类的地方可以自行决定使用哪种策略:
public class TestMain
{
public static void main(String[] args)
{
Strategy strategyA = new StrategyA();
Strategy strategyB = new StrategyB();
Context context = new Context(strategyA);
context.strategyMethod();
context = new Context(strategyB);
context.strategyMethod();
}
}
3.策略模式的使用场景
购物系统
举一个实际例子吧。假如有一个购物系统,在用户付款的时候,会产生很多场景,根据用户的不同情况算出不同用户要付款的金额,这时候最直观的一种做法是:
在付款的里面写N多的if...else if...else,判断用户的场景,根据场景计算用户付款金额。
这种设计明显违反了开闭原则。开闭原则的"闭",指的是对修改关闭,但是这里假如算法又多了几种,那么必须再次修改这个付款的类。
这时候就可以使用策略模式。在付款的类里面持有一个付款接口的引用,每次根据不同场景传入一个具体的策略就好了。比如A类中要使用S0算法,就传入一个S0策略;B类中要使用S1算法,就传入一个S1算法。不需要把判断都放在付款的类中,代码的可读性、可维护性也更高了。付款这个类甚至可以直接生成一个.class文件放在一个jar包里面供调用。
4.策略模式重点不是实现这些算法,而是如何调用这些算法。在不同情况下使用不同的算法
5.优缺点:
优点:避免了多重条件if...else语句,易于扩展。提供了替代继承的方法。降低耦合。需要新的算法,直接写一个新的类实现接口接好了,满足开闭原则。
6.策略模式和简单工厂模式区别
工厂是静态的,策略的上下文需要创建对象
工厂在不同情况下创建不同对象,策略在不同情况下使用不同算法