不少網絡應用中,涉及到一些內部運算的具體求值邏輯並不可以在開發階段就定下來。這些邏輯須要隨着使用,探測用戶反應,不斷修正。符合的狀況,常見的就是網絡遊戲中的行動收穫計算公式,等等。現 Spads 開發組推出了針對此種狀況的解析公式系統,供你們使用。
此公式解析系統可以計算各類算術運算、邏輯運算和比較運算,能夠鏈接本地函數,支持括號分級,容許逐級設置公式內臨時變量,提供了分支運算符,而且支持 Json 數據格式的運算。系統編寫中使用了不少設計方法,包括概念抽取、繼承、多態、面向接口設計、枚舉、遞歸、工廠等等。數據結構也使用了好用但少見的雙端隊 列。很適合對應狀況的實用以及學習 Java 的設計思路、編程方式。本程序由 Shane Loo LI 設計和編寫,全部的細節都注重了運行效率,在不少細節上都製做了數倍優於爪哇(Java)系統類庫的方法;因爲只須要處理公式,因此語法樹結構單一,也因 此保證了比現有其它注入語言的代碼解釋器更高的執行速度。
下面來介紹一下公式解析系統的用法。
首先,公式經過 ?= 來給變量賦值。這種賦值並非一個運算,而是公式每一行須要且只能出現一次的專屬符號。
Result ?= 38 * 6
公式解析系統用 Result 來表示最終的結果。以上公式表示最終的結果爲 228 。
本系統支持如下算術運算:
求負 -
加 +
減 -
乘 *
除 /
求餘 %
乘方 ^
階乘 !
好比編程
Result ?= ((2^5 - (-13)) % 10)!
可以獲得 120 。
接下來,讓咱們看看公式系統的分支控制。網絡
DayCount ?= 31 DayCost ?= 58.5 Limit ?= 1500 Result ?= DayCount * DayCost > Limit ? "超支了!" ~ "沒超支"
咱們看到整個公式分爲四行。每行聲明瞭一個變量。
實際上在這個公式系統中,並不嚴格要求上邊的公式不可以使用下邊公式聲明的變量,但若是嵌套使用則會拋出異常。
上述公式將獲得一個字符串,內容是「超支了」。
支持的有關運算以下:
大於 >
小於 <
等於 =
與 &
或 |
非 -(這個和 C 語言系列的 ! 有所不一樣)
條件 ?
分支 ~(這個和 C 語言系列的 : 有所不一樣)
這個系統最重要的特性,就是可以把公式中出現的函數,和本地函數綁定起來。
只須要製做 Function 接口的實現類,而且在 FunctionEnum 對其進行註冊,就可以獲得一種能夠在公式中識別的函數。
我最近學習了「約定優於明示」的思想,近期會將這種 FunctionEnum 配置方式進行必定程度的更改。
好比,我提供了內置函數 TOGETHER ,其含義是以第一個參數爲名稱,第二個參數爲值,構成鍵值對;第三個參數爲名稱,第四個參數爲值,構成鍵值對;等等。最終將其組合成 Json 字符串。請看以下公式。數據結構
Name ?= "Shane" Level ?= 16 Result ?= TOGETHER(\"name\", Name, "graduated", Level > 10 ? "畢業了" ~ "沒畢業")
最終結果爲 {"name": "Shane", "graduated": "畢業了"}
說了這麼多公式解析系統的用法。如今來從編程角度介紹一下如何啓用此係統功能。
首先,確定是要導入 .jar 包。而後參看如下代碼。ide
EvaluatorFactory factory = EvaluatorFactory.INST; 函數
Evaluator eva = factory.getEvaluator("Result ?= 28 + 2 / 10.0"); 學習
ExpValue result = eva.evaluate(); lua
System.out.println(result); spa
或者.net
String form = "Result ?= 28 + 2 / 10.0"; 設計
ExpValue result = EvaluatorFactory.INST.getEvaluator(form).evaluate();
首先,計算器工廠是單例的,但之後若是要擴展函數庫,則能夠改寫成多種工廠。獲取工廠後,傳入公式字符串(多行),以經過工廠獲取針對此公式的計算器。而後調用計算器的計算方法,便可得到公式最終的結果。
若有疑問,能夠聯繫 Surmounting@gmail.com
項目包下載地址爲: http://download.csdn.net/detail/shanelooli/4726670
本文也在個人 CSDN 日誌中發表: http://blog.csdn.net/shanelooli/article/details/8142726
ITeye 發表: http://surmounting.iteye.com/blog/1714807
中國開源社區發表: http://my.oschina.net/shane1984/blog/86812