動機:在軟件構建過程當中 ,若是某一特定領域的問題比較複雜,相似的模式不斷重複出現,若是使用普通的編程方式來實現將面臨很是頻繁的變化。在這種狀況下,將特定領域的問題表達爲某種語法規則的句子,而後構建一個解釋器來解釋這樣的句子,從而達到解決問題的目的。
意圖:給定一個語言,定義它的文法的一種表示,並定義一種解釋器,這個解釋器使用該表示來解釋語言中的句子。express
UML圖解:編程
示例:接收中文形式的數字表示並能以羅馬形式數字輸出,應用解釋器模式設計,如:四百七十一萬六千四百五十二 =》4716452。代碼以下ide
namespace Interpreter { /// <summary> /// 定義一個數據上下文 /// </summary> public class Context { string statement="";//待解釋的數據 int data;//解釋以後的數據 public Context (string statement) { this.statement = statement; } public int Data { get { return data; } set { data = value; } } public string Statement { get { return statement; } set { statement = value; } } } /// <summary> /// 抽象表達式解釋器 /// </summary> public abstract class Expression { protected Dictionary<string, int> table = new Dictionary<string, int>(9); public Expression() { table.Add("一", 1); table.Add("二", 2); table.Add("三", 3); table.Add("四", 4); table.Add("五", 5); table.Add("六", 6); table.Add("七", 7); table.Add("八", 8); table.Add("九", 9); } /// <summary> /// 解釋給定的中文表示數字上下文對象 /// </summary> /// <param name="context"></param> public virtual void Interpreter(Context context) { if (context.Statement.Length == 0) { return; } foreach (string key in table.Keys) { int value=table[key]; if (context.Statement.EndsWith(key+GetPostfix())) { context.Data += value * this.Multiplier(); context.Statement = context.Statement.Substring(0, context.Statement.Length - GetLength()); } if (context.Statement.EndsWith("零"))//應對如"四百七十一萬零六千四百零五十二"中出現'零'的狀況 { context.Statement=context.Statement.Substring(0,context.Statement.Length-1); } } } /// <summary> /// 獲取如「六千四百五十二」中,獲取千位的'千'字,百位的'百'字,十位的'十'字 /// </summary> /// <returns></returns> public abstract string GetPostfix(); /// <summary> /// 陪增級數(個-1,十位-10,百位-100,千位-1000) /// </summary> /// <returns></returns> public abstract int Multiplier(); /// <summary> /// 獲取符合文法的一組長度(如獲取「四百」,「五十」的長度) /// </summary> /// <returns></returns> public virtual int GetLength() { return this.GetPostfix().Length + 1; } } /// <summary> /// 個位解釋器 解析個位 /// </summary> public class GeExpression : Expression { public override string GetPostfix() { return ""; } public override int Multiplier() { return 1; } public override int GetLength() { return 1; } } /// <summary> /// 十位解釋器 解析個位+十位 /// </summary> public class ShiExpression : Expression { public override string GetPostfix() { return "十"; } public override int Multiplier() { return 10; } } /// <summary> /// 百位解釋器 解析個位+十位+百位 /// </summary> public class BaiExpresssion : Expression { public override string GetPostfix() { return "百"; } public override int Multiplier() { return 100; } } /// <summary> /// 千位解釋器 解析個位+十位+百位+千位 /// </summary> public class QianExpression : Expression { public override string GetPostfix() { return "千"; } public override int Multiplier() { return 1000; } } /// <summary> /// 萬位解釋器 解析個位+十位+百位+千位+萬位 /// </summary> public class WanExpression : Expression { public override void Interpreter(Context context) { if (context.Statement.Length == 0) { return; } ArrayList tree = new ArrayList(); tree.Add(new GeExpression()); tree.Add(new ShiExpression()); tree.Add(new BaiExpresssion()); tree.Add(new QianExpression()); foreach (string key in table.Keys) { if (context.Statement.EndsWith(this.GetPostfix())) { int temp = context.Data; context.Data = 0; context.Statement=context.Statement.Substring(0, context.Statement.Length - 1); foreach(Expression expression in tree) { expression.Interpreter(context); } context.Data = temp+this.Multiplier()*context.Data; } } } public override string GetPostfix() { return "萬"; } public override int Multiplier() { return 10000; } } //經過Interpreter模式很容易擴展億相對的YiExpression類 public class App { public static void Main() { string chinese="四百七十一萬六千四百五十二"; Context context =new Context(chinese); ArrayList tree = new ArrayList();//需按順序添加個十百千萬等解釋表達式對象 tree.Add(new GeExpression()); tree.Add(new ShiExpression()); tree.Add(new BaiExpresssion()); tree.Add(new QianExpression()); tree.Add(new WanExpression()); foreach (Expression exp in tree) { exp.Interpreter(context); } Console.WriteLine("{0}={1}",chinese,context.Data); } } }
Interpreter模式的幾個要點:工具
1.Interpreter模式的應用場景時Interpreter模式應用中的難點,只有知足「業務規則頻繁變化,且 相似的模式不斷重複出現,而且容易抽象爲語法規則的問題」才合適使用Interpreter模式。this
2.使用Interpreter模式來表示文法規則,從而能夠使用面向對象技巧來方便地「擴展」文法。spa
3.Interpreter模式比較適合簡單的文法表示,對於複雜的文法表示,Interpreter模式會產生比較大的類 層次結構,須要求助於語法分析生成器這樣的標準工具。設計