本文為 C++ Software Design 書的第 21 節內容。
// Interface
class CalculatorCommand
{
public:
virtual int execute(int i) const = 0;
virtual int undo(int i) const = 0;
};
class Add : public CalculatorCommand
{
public:
explicit Add (int operand) : operand_{operand} {}
int execute(int i) const override { return i + operand_; }
int undo(int i) const override { return i - operand_; }
private:
int operand_{};
};
class Subtract : public CalculatorCommand
{
public:
explicit Subtract (int operand) : operand_{operand} {}
int execute(int i) const override { return i - operand_; }
int undo(int i) const override { return i + operand_; }
private:
int operand_{};
};
class Calculator
{
public:
void compute(std::unique_ptr<CalculatorCommand> command)
{
current_ = command->execute(current_);
stack_.push(std::move(command));
}
void undoLast ()
{
if (stack_.empty()) return;
auto command = std::move(stack_.top());
stack_.pop();
current_ = command->undo(current_);
}
private:
int current_{};
std::stack<std::unique_ptr<CalculatorCommand>> stack_;
};
可以看出 Calculator class 支援 CalculatorCommand 介面,並且也能 undo。
Command Pattern 與 Strategy Pattern 最大的差別是在設計時想要的是 what 還是 how。也就是說 Command Pattern 的概念是直接去做想要的動作,而 Strategy Pattern 則是定下了如何做這個動作的規則。
如果將計算機的例子寫成 Strategy Pattern 的話會像以下例子:
class CalculatorStrategy
{
public:
virtual int compute(int i) const = 0;
};
class Calculator
{
public:
void set(std::unique_ptr<CalculatorStrategy> op) { op_ = op; }
void compute(int val) { current_ = op_->compute(val); }
private:
int current_;
std::unique_ptr<CalculatorStrategy> op_;
}
可以看出 Strategy Pattern 必須先 set 再 compute,而 Command Pattern 就直接計算結果了。
沒有留言:
張貼留言