热门问题
时间线
聊天
视角
策略模式
軟件設計模式 来自维基百科,自由的百科全书
Remove ads
在计算机编程中,策略模式(英语:strategy pattern,也叫做英语:policy pattern),是一种行为型软件设计模式,它确使可以在运行时选择算法。不再直接的实现一个单一的算法,代码接收运行时指令,选择一个算法家族中的某个算法[1]。

概述
策略模式定义了一族可互换代替的算法(业务规则),并封装了每个算法。
结构

在上面的UML类图中,Context类不直接实现算法。Context转而提及Strategy接口来实行一个算法(strategy.algorithm()),这使得Context独立于算法是如何是实现的。Strategy1和Strategy2类实现了Strategy接口,就是说实现(封装)了一个算法。
UML序列图展示运行时交互:Context对象委托一个算法至不同的Strategy对象。首先Context调用algorithm()于Strategy1对象之上,它实行算法并将结果返回给Context。此后,Context变更它的策略并调用algorithm()在Strategy2对象之上,它实行一个算法并将结果返回给Context。
示例
下面是C++的例子:
#include <iostream>
using namespace std;
class StrategyInterface {
public:
    virtual void execute() = 0;
};
class ConcreteStrategyA: public StrategyInterface {
public:
    virtual void execute() {
        cout << "Called ConcreteStrategyA execute method" << endl;
    }
};
class ConcreteStrategyB: public StrategyInterface {
public:
    virtual void execute() {
        cout << "Called ConcreteStrategyB execute method" << endl;
    }
};
class Context {
private:
    StrategyInterface *_strategy;
public:
    Context(StrategyInterface *strategy):_strategy(strategy) {
    }
    void set_strategy(StrategyInterface *strategy) {
        _strategy = strategy;
    }
    void execute() {
        _strategy->execute();
    }
};
int main(int argc, char *argv[])
{
    ConcreteStrategyA concreteStrategyA;
    ConcreteStrategyB concreteStrategyB;
    Context contextA(&concreteStrategyA);
    Context contextB(&concreteStrategyB);
    contextA.execute();
    contextB.execute();
    
    contextA.set_strategy(&concreteStrategyB);
    contextA.execute();
    return 0;
}
Remove ads
下面是Java的例子:
// The classes that implement a concrete strategy should implement this
// The context class uses this to call the concrete strategy
interface Strategy {
    void execute();
}
// Implements the algorithm using the strategy interface
class FirstStrategy implements Strategy {
    public void execute() {
        System.out.println("Called FirstStrategy.execute()");
    }
}
class SecondStrategy implements Strategy {
    public void execute() {
        System.out.println("Called SecondStrategy.execute()");
    }
}
// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {
    Strategy strategy;
    // Constructor
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    public void execute() {
        this.strategy.execute();
    }
}
//StrategyExample test application
class StrategyExample {
    public static void main(String[] args) {
        Context context;
        // Three contexts following different strategies
        context = new Context(new FirstStrategy());
        context.execute();
        context = new Context(new SecondStrategy());
        context.execute();
    }
}
Remove ads
下面是C#的例子:
using System;
namespace Wikipedia.Patterns.Strategy {
    // The classes that implement a concrete strategy should implement this
    // The context class uses this to call the concrete strategy
    interface IStrategy {
        void Execute();
    }
    // Implements the algorithm using the strategy interface
    class ConcreteStrategyA : IStrategy {
        public void Execute() {
            Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
        }
    }
    class ConcreteStrategyB : IStrategy {
        public void Execute() {
            Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
        }
    }
    // Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
    class Context {
        IStrategy strategy;
        // Constructor
        public Context(IStrategy strategy) {
            this.strategy = strategy;
        }
        public void Execute() {
            strategy.Execute();
        }
    }
    // MainApp test application
    class MainApp {
        static void Main() {
            Context context;
            // Three contexts following different strategies
            context = new Context(new ConcreteStrategyA());
            context.Execute();
            context = new Context(new ConcreteStrategyB());
            context.Execute();
        }
    }
}
Remove ads
下面是Python的例子:
from abc import ABC, abstractmethod
class Strategy(ABC):
    @abstractmethod
    def __call__(self): pass
class ConcreteStrategyA(Strategy):
    def __call__(self): 
        print("Called ConcreteStrategyA execute method")
class ConcreteStrategyB(Strategy):
    def __call__(self): 
        print("Called ConcreteStrategyB execute method")
class Context():
    def __init__(self, strategy):
        self.strategy = strategy
    def __call__(self):
        self.strategy()
其执行:
>>> context = Context(ConcreteStrategyA())
>>> context()
Called ConcreteStrategyA execute method
>>> context = Context(ConcreteStrategyB())
>>> context()
Called ConcreteStrategyB execute method
Remove ads
引用
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads
