设计模式之策略模式

定义:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

角色:
Context(应用场景):需要使用ConcreteStrategy提供的算法。 内部维护一个Strategy的实例,通过动态改变Strategy实例(赋值或其他)改变调用的算法。负责动态设置运行时Strategy具体的实现算法。负责跟Strategy之间的交互和数据传递。
Strategy(抽象策略类):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
ConcreteStrategy(具体策略类):实现了Strategy定义的接口,提供具体的算法实现。

结构图:

优点:

1、提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。

2、避免使用多重条件判断,使系统更灵活,并易于扩展。

3、遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

缺点:

1、策略类会增多。

2、所有策略类都需要对外暴露。

使用:Context 是一个使用了某种策略的类。StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。
1.创建一个接口:

public interface Strategy
{
public int doOperation(int num1, int num2);
}
2.创建实现接口的实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class OperationAdd implements Strategy
{
public Override int doOperation(int num1, int num2) {
return num1 + num2;
}
}

public class OperationSubstract implements Strategy
{
public Override int doOperation(int num1, int num2) {
return num1 - num2;
}
}

public class OperationMultiply implements Strategy
{
public Override int doOperation(int num1, int num2) {
return num1 * num2;
}
}

3.创建 Context 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Context 
{
private Strategy strategy;

public Context(Strategy strategy)
{
this.strategy = strategy;
}

public int executeStrategy(int num1, int num2)
{
return strategy.doOperation(num1, num2);
}
}

4.使用 Context 来查看当它改变策略 Strategy 时的行为变化。

1
2
3
4
5
6
7
8
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));