我有一个程序,它应该从控制台读取命令,并根据命令执行几个操作之一。这是我到目前为止所知道的:
void ConwayView::listening_commands() {
string command;
do {
cin >> command;
if ("tick" == command)
{
// to do
}
else if ("start" == command)
{
// to do for start
}
...
} while (EXIT != command);
}如果有大量的命令,使用switch代替if语句会有一些帮助。您建议使用哪些模式来提供交互式命令行?
发布于 2012-11-12 20:33:15
如果命令的数量很少,并且可能的参数真的很少,那么您可以继续切换大小写!
如果命令数量增加,请考虑the command design pattern (这是某种伪装的strategy pattern:cf Using a strategy pattern and a command pattern,用于说明命令和策略模式之间的差异)。
如果您的大多数命令都共享相同行为的一部分,请不要忘记the template method pattern。
如果创建命令对象的复杂性增加了(即解码/理解命令行输入的复杂性),那么您应该开始考虑the interpreter design pattern
如果在解释器模式的帮助下进行设计时,您碰巧看到了一些复杂性(如果解释器需要太多的工作,您会看到语法问题等等),那么您可能应该考虑DSL, domain specific language,并设计适合(并且只适合)您自己的输入的语言。
发布于 2012-11-12 20:32:23
有多种方法可以解决这个问题,什么是“正确”的解决方案是有争议的。如果我要为自己的工作解决这个问题,我会创建一个自定义结构表。类似于:
struct CommandStruct {
char *command;
int (*commandHandler)(/*params*/);
} commandTable[] = {
{ "tick", tickCommand },
{ "start", startCommand },
...
};然后,我的处理循环将遍历该表的每个元素,查找正确的匹配项,例如:
for (int i = 0; i < TABLE_SIZE; ++i) {
if (command == commandTable[i].command) { /* using whatever proper comparison is, of course */
commandTable[i].commandHandler(/*params*/);
break;
}
}发布于 2012-11-12 20:32:29
不是真正的模式,但通常是一个很好的方法:
#include <map>
#include <functional>
#include <string>
#include <iostream>
typedef std::map< std::string, std::function<void(void)> > command_dict;
// ^^^^^^^^
// the signature of your commands. probably should have an error code.
void command1() { std::cout << "commanda" << std::endl; }
void command2() { std::cout << "commandb" << std::endl; }
void command3() { std::cout << "commandc" << std::endl; }
int main() {
command_dict c;
c["a"] = &command1;
c["b"] = &command2;
c["c"] = &command3;
std::string input;
while(std::getline(std::cin, input)) { // quit the program with ctrl-d
auto it = c.find(input);
if(it != end(c)) {
(it->second)(); // execute the command
} else {
std::cout << "command \"" << input << "\" not known" << std::endl;
}
}
}https://stackoverflow.com/questions/13343657
复制相似问题