35解释器模式(Interpreter Pattern)
動機(jī)(Motivate):
??? 在軟件構(gòu)建過程中,如果某一特定領(lǐng)域的問題比較復(fù)雜,類似的模式不斷重復(fù)出現(xiàn),如果使用普通的編程方式來實現(xiàn)將面臨非常頻繁的變化。
??? 在這種情況下,將特定領(lǐng)域的問題表達(dá)為某種文法規(guī)則下的句子,然后構(gòu)建一個解釋器來解釋這樣的句子,從而達(dá)到解決問題的目的。
意圖(Intent):
????給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
結(jié)構(gòu)圖(Struct):
??? ?? ?? ??
生活中的例子:
??? ?? ?? ???
適用性:
1.當(dāng)有一個語言需要解釋執(zhí)行,并且你可將該語言中的句子表示為一個抽象語法樹時,可使用解釋器模式。
而當(dāng)存在以下情況時該模式效果最好:
2.該文法簡單對于復(fù)雜的文法,文法的類層次變得龐大而無法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構(gòu)建抽象語法樹即可解釋表達(dá)工,這樣可以節(jié)省空間而且還可能節(jié)省時間。
3.效率不是一個關(guān)鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實現(xiàn)的,而是首先將它們轉(zhuǎn)換成另一種
形式。例如:正則表達(dá)式通常被轉(zhuǎn)換成狀態(tài)機(jī)。但即使在這種情況下,轉(zhuǎn)換器仍可用解釋器模式實現(xiàn),該模式仍
是有用的。
代碼實現(xiàn):
客戶端代碼如下:
?2?????{
?3?????????static?void?Main(string[]?args)
?4?????????{
?5?????????????string?roman?=?"五千四百三十二";?//5432
?6?????????????Context?context?=?new?Context(roman);
?7?
?8?????????????//Build?the?'parse?tree'
?9?????????????ArrayList?tree?=?new?ArrayList();
10?????????????tree.Add(new?OneExpression());
11?????????????tree.Add(new?TenExpression());
12?????????????tree.Add(new?HundredExpression());
13?????????????tree.Add(new?ThousandExpression());????????????
14?
15?????????????//Interpret
16?????????????foreach?(Expression?exp?in?tree)
17?????????????{
18?????????????????exp.Interpret(context);
19?????????????}
20?????????????Console.WriteLine("{0}?=?{1}",?roman,?context.Data);
21?????????????//Wait?for?user
22?????????????Console.Read();
23?????????}
24?????}
創(chuàng)建一個抽象類Expression,來描述共同的操作。
?1?????public?abstract?class?Expression?2?????{
?3?????????protected?Dictionary<string,?int>?table?=?new?Dictionary<string,?int>(9);
?4?????????public?Expression()
?5?????????{
?6?????????????table.Add("一",?1);
?7?????????????table.Add("二",?2);
?8?????????????table.Add("三",?3);
?9?????????????table.Add("四",?4);
10?????????????table.Add("五",?5);
11?????????????table.Add("六",?6);
12?????????????table.Add("七",?7);
13?????????????table.Add("八",?8);
14?????????????table.Add("九",?9);
15?????????}
16?????????public?virtual?void?Interpret(Context?context)
17?????????{
18??????????if(context.Statement.Length==0)
19?????????????{
20???????????????return;
21?????????????}
22?????????foreach(string?key?in?table.Keys)
23?????????{
24??????????int?value=table[key];
25??????????if(context.Statement.EndsWith(key?+?GetPostifix()))
26?????????????{?
27???????????????context.Data?+=value*Multiplier();
28???????????????context.Statement?=?context.Statement.Substring(0,context.Statement.Length-?this.GetLength());
29?????????????}
30?
31?????????????if(context.Statement.EndsWith("零"))
32?????????????{
33?????????????????context.Statement?=?context.Statement.Substring(0,?context.Statement.Length?-?1);
34?????????????}
35?????????????if?(context.Statement.Length?==?0)
36?????????????{
37?????????????????return;
38?????????????}
39??????????}
40????????}
41?
42?????????public?abstract?string?GetPostifix();
43?????????public?abstract?int?Multiplier();
44?????????public?virtual?int?GetLength()
45?????????{
46?????????????return?this.GetPostifix().Length?+?1;
47?????????}
48?????}
然后創(chuàng)建一個公共類Context,定義一些全局信息。
?1????public?class?Context?2?????{
?3?????????private?string?statement;
?4?????????private?int?data;
?5?
?6?????????//Constructor
?7?????????public?Context(string?statement)
?8?????????{
?9?????????????this.statement?=?statement;
10?????????}
11?????????//Properties
12?????????public?string?Statement
13?????????{
14?????????????get?{?return?statement;?}
15?????????????set?{?statement?=?value;?}
16?????????}
17?????????public?int??Data
18?????????{
19?????????????get?{?return?data;?}
20?????????????set?{?data??=?value;?}
21?????????}
22?????}
?
?1?????public?class?OneExpression?:?Expression?2?????{
?3?????????public?override?string?GetPostifix()
?4?????????{
?5?????????????return?"";
?6?????????}
?7?????????public?override?int?Multiplier()?{?return?1;?}
?8?????????public?override?int?GetLength()
?9?????????{
10?????????????return?1;
11?????????}
12?????}
13?????public?class?TenExpression?:?Expression
14?????{
15?????????public?override?string?GetPostifix()
16?????????{
17?????????????return?"十";
18?????????}
19?????????public?override?int?Multiplier()?{?return?10;?}
20?????????public?override?int?GetLength()
21?????????{
22?????????????return?2;
23?????????}
24?????}
25?????public?class?HundredExpression?:?Expression
26?????{
27?????????public?override?string?GetPostifix()
28?????????{
29?????????????return?"百";
30?????????}
31?????????public?override?int?Multiplier()?{?return?100;?}
32?????????public?override?int?GetLength()
33?????????{
34?????????????return?2;
35?????????}
36?????}
37?????public?class?ThousandExpression?:?Expression
38?????{
39?????????public?override?string?GetPostifix()
40?????????{
41?????????????return?"千";
42?????????}
43?????????public?override?int?Multiplier()?{?return?1000;?}
44?????????public?override?int?GetLength()
45?????????{
46?????????????return?2;
47?????????}
48?????}
Interpreter實現(xiàn)要點:
? Interpreter模式的應(yīng)用場合是interpreter模式應(yīng)用中的難點,只有滿足"業(yè)務(wù)規(guī)則頻繁變化,且類似的模式不斷重復(fù)出現(xiàn),并且容易抽象為語法規(guī)則的問題"才適合使用Interpreter模式。
??? 使用Interpreter模式來表示文法規(guī)則,從而可以使用面向?qū)ο蠹记蓙矸奖愕亍皵U(kuò)展”文法。
??? Interpreter模式比較適合簡單的文法表示,對于復(fù)雜的文法表示,Interpreter模式會產(chǎn)生比較大的類層次結(jié)構(gòu),需要求助于語法分析生成器這樣的標(biāo)準(zhǔn)工具。
總結(jié)
以上是生活随笔為你收集整理的35解释器模式(Interpreter Pattern)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是ASP.NET Boilerpla
- 下一篇: 25外观模式(Facade Patter