1. 程式人生 > >Head First設計模式之解釋器模式

Head First設計模式之解釋器模式

mes eval form value oid 對象 arc share hive

一、定義

給定一個語言,定義它的文法表示,並定義一個解釋器,這個解釋器使用該標識來解釋語言中的句子。

主要解決:對於一些固定文法構建一個解釋句子的解釋器。

何時使用:如果一種特定類型的問題發生的頻率足夠高,那麽可能就值得將該問題的各個實例表述為一個簡單語言中的句子。這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決該問題。

如何解決:構件語法樹,定義終結符與非終結符。

二、結構

技術分享

  組成:   

  AbstractExpression(抽象表達式):定義解釋器的接口,約定解釋器的解釋操作。

  TerminalExpression(終結符表達式):用來實現語法規則中和終結符相關的操作,不再包含其它的解釋器,如果用組合模式來構建抽象語法樹的話,就相當於組合模式中的葉子對象,可以有多種終結符解釋器。

  NonterminalExpression(非終結符表達式):用來實現語法規則中非終結符相關的操作,通常一個解釋器對應一個語法規則,可以包含其它的解釋器,如果用組合模式來構建抽象語法樹的話,就相當於組合模式中的組合對象,可以有多種非終結符解釋器。

  Context(上下文):它包含了解釋器之外一些其他的全局信息;通常包含各個解釋器需要的數據,或是公共的功能。

  Client(客戶端):指的是使用解釋器的客戶端,通常在這裏去把按照語言的語法做的表達式,轉換成為使用解釋器對象描述的抽象語法樹,然後調用解釋操作。

三、適用場景

1、可以將一個需要解釋執行的語言中的句子表示為一個抽象語法樹。

2、一些重復出現的問題可以用一種簡單的語言來進行表達。

3、一個簡單語法需要解釋的場景。

四、優缺點

優點: 1、可擴展性比較好,靈活。 2、增加了新的解釋表達式的方式。 3、易於實現簡單文法。

缺點: 1、可利用場景比較少。 2、對於復雜的文法比較難維護。 3、解釋器模式會引起類膨脹。 4、解釋器模式采用遞歸調用方法。

五、實現

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns.Interpreter { class Program { static void Main(string[] args) { Console.WriteLine(ReplyClient.ApplyContent("Y0001")); Console.WriteLine(ReplyClient.ApplyContent("y0002")); Console.WriteLine(ReplyClient.ApplyContent("N0003")); Console.WriteLine(ReplyClient.ApplyContent("n0004")); } } /// <summary> /// 回復內容 /// </summary> public class ReplyContent { private string _ReplyText; public string ReplyText { get { return _ReplyText; } set { _ReplyText = value; } } } public abstract class InterPreter { public string ConvertContent(ReplyContent content) { if (content.ReplyText.Length == 0) return "請按規則回復審批短信."; return Excute(content.ReplyText); } public abstract string Excute(string key); } public class Approve : InterPreter { public override string Excute(string key) { if (key == "Y" || key == "y") { return "同意"; } else if (key == "N" || key == "n") { return "拒絕"; } else { return "回復內容有誤,請重新回復."; } } } public class DocumentNum : InterPreter { public Dictionary<string, string> OddNum { get { Dictionary<string, string> OddID = new Dictionary<string, string>(); OddID.Add("0001", "123890890892345"); OddID.Add("0002", "123456717012345"); OddID.Add("0003", "123456669012345"); OddID.Add("0004", "123423444012345"); OddID.Add("0005", "123467845345345"); OddID.Add("0006", "123231234564345"); OddID.Add("0007", "128797897867745"); return OddID; } } public override string Excute(string key) { string value = null; if (OddNum.TryGetValue(key, out value)) { return value; } else { return "沒找到對應的單號."; } } } public class ReplyClient { public static string ApplyContent(string replayValue) { string result = string.Empty; string approvevalue = replayValue.Substring(0, 1); string oddIDvalue = replayValue.Substring(1, 4); ReplyContent content = new ReplyContent(); content.ReplyText = approvevalue; InterPreter expression = new Approve(); result = string.Format("你{0}", expression.ConvertContent(content)); expression = new DocumentNum(); content.ReplyText = oddIDvalue; result += string.Format("單號是{0}的申請.\n", expression.ConvertContent(content)); return result; } } }

參考

http://www.runoob.com/design-pattern/interpreter-pattern.html

http://www.cnblogs.com/JsonShare/p/7367535.html

http://www.cnblogs.com/springyangwc/archive/2011/05/05/2037146.html


歡迎閱讀本系列文章:Head First設計模式之目錄

Head First設計模式之解釋器模式