我想要你对以下伪代码的建议.请建议我如何改进它,无论我是否可以使用一些设计模式.
// i'm receiving a string containing : id operation arguments data = read(socket); tokens = tokenize(data," "); // tokenize the string based on spaces if(tokens[0] == "A") { if(tokens[1] == "some_operation") { // here goes code for some_operation , will use the remaining tokens as arguments for function calls } else if(tokens[1] == "some_other_operation") { // here goes code for some_other_operation , will use the remaining tokens } ... else { // unknown operation } } else if(tokens[0] == "B") { if(tokens[1] == "some_operation_for_B") { // do some operation for B } else if(tokens[1] == "yet_another_operation") { // do yet_another_operation for B } ... else { // unknown operation } }
我希望你明白这一点.问题是我拥有大量的id并且每个都拥有它自己的操作,我认为有10个代码的屏幕包含很多if和其他if有点难看.
为每个实现通用接口的ID都有一个类.基本上是战略模式 IIRC.
所以你要调用(伪)代码,如:
StrategyFactory.GetStrategy(tokens[0]).parse(tokens[1..n])
首先记下你支持的语法,然后编写代码来支持它.
使用BNF符号非常适合.使用Spirit库作为代码部分非常简单.
Command := ACommand | BCommand ACommand := 'A' AOperation AOperation := 'some_operation' | 'some_other_operation' BCommand := 'B' BOperation BOperation := 'some_operation_for_B' | 'some_other_operation_for_B'
这很容易转换为Spirit解析器.每个生产规则都将成为一个单行,每个结束符号将被转换为一个函数.
#include "stdafx.h" #include#include #include using namespace std; using namespace boost::spirit; namespace { void AOperation(char const*, char const*) { cout << "AOperation\n"; } void AOtherOperation(char const*, char const*) { cout << "AOtherOperation\n"; } void BOperation(char const*, char const*) { cout << "BOperation\n"; } void BOtherOperation(char const*, char const*) { cout << "BOtherOperation\n"; } } struct arguments : public grammar { template struct definition { definition(arguments const& /*self*/) { command = acommand | bcommand; acommand = chlit ('A') >> ( a_someoperation | a_someotheroperation ); a_someoperation = str_p( "some_operation" ) [ &AOperation ]; a_someotheroperation = str_p( "some_other_operation" )[ &AOtherOperation ]; bcommand = chlit ('B') >> ( b_someoperation | b_someotheroperation ); b_someoperation = str_p( "some_operation_for_B" ) [ &BOperation ]; b_someotheroperation = str_p( "some_other_operation_for_B" )[ &BOtherOperation ]; } rule command; rule acommand, bcommand; rule a_someoperation, a_someotheroperation; rule b_someoperation, b_someotheroperation; rule const& start() const { return command; } }; }; template bool test( parse_info pi ) { if( pi.full ) { cout << "success" << endl; return true; } else { cout << "fail" << endl; return false; } } int _tmain(int argc, _TCHAR* argv[]) { arguments args; test( parse( "A some_operation", args, space_p ) ); test( parse( "A some_other_operation", args, space_p ) ); test( parse( "B some_operation_for_B", args, space_p ) ); test( parse( "B some_other_operation_for_B", args, space_p ) ); test( parse( "A some_other_operation_for_B", args, space_p ) ); return 0; }