简介
策略模式,它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
结构图
Strategy类,定义所有支持的算法的公共接口
// 抽象算法类
abstract class Strategy {
// 算法方法
public abstract void AlgorithmInterface();
}
ConcreteStrategy,封装了具体的算法或行为,继承于Strategy
// 具体算法A
class ConcreteStrategyA : Strategy {
public override void AlgorithmInterface(){
Console.WriteLine("算法A实现");
}
}
class ConcreteStrategyB : Strategy {
public override void AlgorithmInterface() {
Console.WriteLine("算法实现B");
}
}
class ConcreteStrategyC : Strategy {
public override void AlgorithmInterface() {
Console.WriteLine("算法实现C");
}
}
Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。
class Context {
Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void ContextInterface() {
strategy.AlgorithmInterface();
}
}
客户端代码
static void main(String[] args) {
Context context;
context = new Context(new ConcreteStrategyA();
context.ContextInterface();
context = new Context(new ConcreteStrategyB();
context.ContextInterface();
context = new Context(new ConcreteStrategyC();
context.ContextInterface();
}
但是这种方式,需要通过客户端去判断用哪一个算法。我们可以结合简单工厂模式来改造一下。
改造后的Context
class Context {
Strategy strategy;
public Context(string type) {
switch(type) {
case "A":
strategy = new ConcreteStrategyA();
break;
case "B":
strategy = new ConcreteStrategyB();
break;
case "C":
strategy = new ConcreteStrategyC();
break;
}
}
public void ContextInterface() {
strategy.AlgorithmInterface();
}
}
客户端代码
Context context = new Context("A");
context.ContextInterface();
Context context = new Context("B");
context.ContextInterface();
这样,我们客户端的代码就简便多了。
回顾
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
如果使用场景满足以下的某种条件,那我们就可以考虑使用策略模式。1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
但是使用策略模式会导致策略类增多,而且所有策略类都需要对外暴露。所以具体情况还是要具体分析。