设计模式(九)—— 策略模式

策略模式

定义

定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

策略模式通用类图

  • Context:封装角色,起承上启下封装作用,屏蔽高层模块对算法的、策略的直接访问,封装可能存在的变化。
  • Strategy:抽象策略角色,策略、算法的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • ConcreteStrategy:具体策略角色,实现抽象策略中的操作。

具体实现:

抽象策略角色:

1
2
3
public interface Strategy {
void doSomething();
}

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
public class ContreteStrategy1 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略1执行");
}
}
public class ContreteStrategy2 implements Strategy {
@Override
public void doSomething() {
System.out.println("具体策略2执行");
}
}

封装角色

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

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

public void doSomething(){
this.strategy.doSomething();
}
}

Client的main方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {

public static void main(String[] args) {
Strategy strategy1 = new ContreteStrategy1();
Strategy strategy2 = new ContreteStrategy2();
Context context1 = new Context(strategy1);
Context context2 = new Context(strategy2);
context1.doSomething();
context2.doSomething();

}
}
// 输出结果
具体策略1执行
具体策略2执行

策略模式就是采用了面向对象的继承和多态机制。

优点

  1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句。
  2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
  3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
  4. 策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
  5. 策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

缺点

  1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
  2. 策略模式造成很多的策略类,所有策略类都需要对外暴露。

使用场景

  • 多个类只有在算法或香味上不同的场景
  • 算法需要自由切换的场景
  • 需要屏蔽算法规则的场景

扩展

在一个使用策略模式的系统中,当存在的策略很多时,客户端管理所有策略算法将变得很复杂,如果在环境类中使用策略工厂模式来管理这些策略类将大大减少客户端的工作复杂度。

代码:GitHub


欢迎关注公众号:
公众号微信

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
显示 Gitment 评论