Nar*_*rek 8 oop encapsulation design-patterns command-pattern
命令模式用于封装对象中的命令.但为什么不使用函数指针呢?为什么我需要为每个操作子类化Command?相反,我可以有不同的函数并调用函数指针.
Mik*_*our 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
Run Code Online (Sandbox Code Playgroud)
如果您使用普通函数指针,那么您可能需要一个不同的函数来处理您想要打印的所有内容.
为什么我需要为每个操作子类化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
Run Code Online (Sandbox Code Playgroud)
命令模式不仅仅是执行一个函数.它将数据和逻辑封装在类中,并提供可以轻松作为参数传递的对象.除了执行任务之外,它还可以触发事件,解析和清理数据等等,这就是继承和模板方法派上用场的地方,你不会使用函数指针.此外,使用命令实现撤消和重做非常容易.