文章出處

在今天,讀書有時是件“麻煩”事。它需要你付出時間,付出精力,還要付出一份心境。--僅以《大話設計模式》來祭奠那逝去的……

解釋器模式:給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子

在軟件開發特別是DSL開發中常常需要使用一些相對較復雜的業務語言,如果業務語言使用頻率足夠高,且使用普通的編程模式來實現會導致非常復雜的變化,那 么就可以考慮使用解釋器模式構建一個解釋器對復雜的業務語言進行翻譯。這種做法雖然效率相對較低,但可以允許用戶使用自定義的業務語言來處理邏輯,因此在 效率不是關鍵問題的場合還是較為有用的。

在實際的系統開發中使用的非常少,因為它會引起效率、性能以及維護等問題,一般在大中型的框架型項目能夠找到它的身影,比如一些數據分析工具、報表設計工具、科學計算工具等等,若你確實遇到“一種特定類型的問題發生的頻率足夠高”的情況,準備使用解釋器模式時,可以考慮一下Expression4J、MESP(Math Expression String Parser)、Jep等開源的解析工具包(這三個開源產品都可以百度、Google中搜索到,請讀者自行查詢),功能都異常強大,而且非常容易使用,效率也還不錯,實現大多數的數學運算完全沒有問題,自己沒有必要從頭開始編寫解釋器,有人已經建立了一條康莊大道,何必再走自己的泥濘小路呢?

1.四則運算

  金融行業軟件中,經常會遇到各種匯總、報表之類牽涉到四則運算,下面是簡單的實現

  定義上下文類(這個類根據需求自己擴展,也可以不定義)

    /// <summary>
    /// 上下文類(包含解釋器意外的全局信息)
    /// </summary>
    public class Context
    {
        /// <summary>
        /// 表達式(1+2)
        /// </summary>
        public string Expression { get; set; }

        /// <summary>
        /// 運算結果
        /// </summary>
        public int Result { get; set; }
    }

   定義解釋器

    /// <summary>
    /// 解釋器(定義AbstractExpression接口或者抽象類)
    /// </summary>
    public abstract class AbstractExpression
    {
        public abstract int Interpret(int value, int result);
    }

    /// <summary>
    /// 加法解釋器
    /// </summary>
    public class AddExpression : AbstractExpression
    {
        public override int Interpret(int value, int result)
        {
            return result + value;
        }
    }

    /// <summary>
    /// 減法解釋器
    /// </summary>
    public class SubExpression : AbstractExpression
    {
        public override int Interpret(int value, int result)
        {
            return result - value;
        }
    }

   定義一個幫助類,方便客戶端調用

    /// <summary>
    /// 對解釋器進行封裝,方便客戶端使用
    /// </summary>
    public class Operation
    {
        public static void Operate(Context context)
        {
            context.Expression = "+" + context.Expression;

            //對表達式進行封裝
            List<string> list = new List<string>();

            while (context.Expression.Length > 0)
            {
                list.Add(context.Expression.Substring(0, 2));

                context.Expression = context.Expression.Substring(2);
            }

            foreach (var v in list)
            {
                AbstractExpression expression = null;

                var operate = v.Substring(0, 1);

                switch (operate)
                {
                    case "+":
                        expression = new AddExpression();
                        break;
                    case "-":
                        expression = new SubExpression();
                        break;
                }

                context.Result = expression.Interpret(Convert.ToInt32(v.Substring(1, 1)), context.Result);
            }

            Console.WriteLine("運算結果為:{0}", context.Result);
        }
    }

   開啟場景模擬

        static void Main(string[] args)
        {
            var str = "3+5+7";

            Operation.Operate(new Context() { Expression = str, Result = 0 });
        }

2.多語言翻譯,待續……例子(http://www.cnblogs.com/saville/p/3379533.html)

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()