設計模式C++版:第十九式直譯器模式
阿新 • • 發佈:2019-02-14
直譯器模式:給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該解釋語言中的句子。比如配置檔案,比如正則表示式,比如瀏覽器對HTML。當有一個語言需要解釋執行,並且可將該語言中的句子表示為一個抽象語法樹時,可以使用直譯器模式。
#pragma once #include<stdio.h> #include<string> using std::string; //文字類 class Context { public: void settext(const string& text) { this->m_text = text; } string gettext() { return m_text; } private: string m_text; }; // 解釋類 class Expression { public: virtual ~Expression(){ } void interpret(Context &context) { if (context.gettext().length()==0) { return; } else { string key = context.gettext().substr(0, 1); context.settext(context.gettext().substr(2)); double value = atof(context.gettext().substr(0,context.gettext().find(' ')+1).c_str()); context.settext(context.gettext().substr(context.gettext().find(' ')+1)); excute(key, value); } } virtual void excute(const string& key, double value){ } }; class Note:public Expression { public: virtual void excute(const string& key, double value) { char not = key.at(0); switch(not) { case'C': not = '1'; break; case'D': not = '2'; break; case'E': not = '3'; break; case'F': not = '4'; break; case'G': not = '5'; break; case'A': not = '6'; break; case'B': not = '7'; break; default: break; } printf("%c ", not); } }; class Scale :public Expression { public: virtual void excute(const string& key, double value) { string key0 = ""; int val = value; switch (val) { case 1: key0 ="低音"; break; case 2: key0 = "中音"; break; case 3: key0 = "高音"; break; default: break; } printf("%s ", key0.c_str()); } }; int main() { Context context; context.settext("O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 "); while (context.gettext().length() > 0) { string str = context.gettext().substr(0, 1); char not = str.at(0); Expression * expr = nullptr; switch (not) { case 'C': case 'D': case 'E': case 'F': case 'G': case 'A': case 'B': case 'P': expr = new Note; break; case 'O': expr = new Scale; break; default: break; } expr->interpret(context); //引用 delete expr; expr = nullptr; } printf("\n"); return 0; }
說到底如果狀態和型別多的時候,switch case 還是比狀態等模式使用方便。效率高,還清晰,當然使用陣列也可以。