#include <iostream>
class Strategy
{
public:
virtual void execute() = 0;
};
class Strategy1 : public Strategy
{
public:
virtual void execute() override { std::cout << "executed1\n"; }
};
class Strategy2 : public Strategy
{
public:
virtual void execute() override { std::cout << "executed2\n"; }
};
template <typename S>
class StaticStrategy
{
S strategy;
public:
void execute()
{
strategy.execute();
}
};
class DynamicStrategy
{
Strategy* strategy;
public:
DynamicStrategy(Strategy* strategy) : strategy(strategy) {}
void execute()
{
strategy->execute();
}
void setStrategy(Strategy* newStrategy)
{
delete strategy;
strategy = newStrategy;
}
~DynamicStrategy()
{
delete strategy;
}
};
int main()
{
StaticStrategy<Strategy1> staticStrategy;
staticStrategy.execute();
DynamicStrategy dynamicStrategy(new Strategy1{});
dynamicStrategy.execute();
dynamicStrategy.setStrategy(new Strategy2{});
dynamicStrategy.execute();
}
这是一个用c++写的静态和动态策略模式的例子。我想知道为什么有人会使用静态策略而不是动态策略。似乎动态策略可以完成静态策略的所有工作,但也有更多的灵活性,因为策略可以在运行时改变。谁能举个例子说明静态策略比动态策略好?
严格来说,静态版本的功能更强大,在某些方面也更容易使用。
静态版本只要求 S
拥有成员功能 execute
而动态版本则要求用户继承自 Strategy
.
静态版本对分配策略或寿命没有任何要求,而在代码段中,动态版本需要堆分配。动态版本的另一种选择是,如果它不拥有所有权,则可以不进行分配,在这种情况下,客户端必须关注 Strategy
寿命。
给定静态版本,客户机如果想要堆分配,可以抹去策略类型,以单一策略类型进行堆分配。但是给定了上面的动态版本,客户端不能撤销对堆分配的要求。
静态版本对于编译器来说是完全可见的,这些信息可以用于优化。而动态版本则是间接通过 Strategy
基类,所以内联不会发生,除非编译器能证明(或推测)具体的 Strategy
正在使用的类。