命令模式用于在对象中封装命令。但为什么不使用函数指针呢?为什么我需要为每个操作子类化Command?相反,我可以使用不同的函数并调用函数指针。
答案 0 :(得分:12)
但为什么不使用函数指针。
因为函数指针不能存储任意状态。您经常希望在创建命令时对其进行参数化。例如:
struct command {
virtual ~command() {}
virtual void do_it() = 0;
};
struct say_something : command {
// store a message to print later
say_something(std::string message) : message(message) {}
// print the stored message
void do_it() override {std::cout << message << '\n';}
std::string message;
};
std::unique_ptr<command> say_hello(new say_something("Hello!"));
// later
say_hello->do_it(); // prints stored string
如果您使用普通函数指针,那么您可能需要一个不同的函数来处理您想要打印的所有内容。
为什么我需要为每个操作创建Command类的子类?
因为这就是老式OOP的工作原理;虽然如上所述,你可以使用这样一个事实:它是一个参数化它的对象而不是它的子类。
幸运的是,现代C ++有更好的设施:
typedef std::function<void()> command;
// print a static string
command say_hello = []{std::cout << "Hello!\n";};
// store a string to print later
std::string goodbye = "Goodbye!";
command say_goodbye = [goodbye]{std::cout << goodbye << '\n';};
// later
say_hello(); // prints static string
say_goodbye(); // prints string stored in the command
答案 1 :(得分:6)
命令模式不仅仅是执行一个函数。它将数据和逻辑封装在类中,并提供可以轻松作为参数传递的对象。除了执行任务之外,它还可以触发事件,解析和清理数据等等,以及继承和模板方法派上用场的好处,您将无法使用函数指针。此外,使用命令实现撤消和重做非常简单。