2011-01-12 47 views
8

下面是JavaScript專家的實現細節問題。在JavaScript中實現複雜的決策表

我有一個用戶界面,其中的字段值以複雜的方式依賴於七位輸入值的值。在用戶看到更多應用程序時,對於可能的128個值中的任何一個,應該顯示什麼內容纔會定期更改?

現在,我已經通過if-then-else comb來實現它作爲決策樹,但是它在需求變化下很脆弱,很難正確判斷。

我想過

一種實現方法是使數值數組從0x0到0x7F的,然後存儲封閉在每個位置 -

var tbl; // initialize it with the values 
    ... 
tbl[0x42] = function(){ doAThing(); doAnotherThing(); } 

,然後與調用它們

tbl[bitsIn](); 

這至少使決策邏輯成爲一組任務。

問:有沒有更好的方法?

(更新:哇靠,你怎麼對「AJAX iphone標籤」即行那裏得到難怪這是一個有點令人費解。)

更新

到底發生了什麼?基本上我採取了第四種選擇,雖然與我檢查過的類似。這個邏輯非常複雜,我終於建立了一個Python程序來在服務器中生成一個真值表(實際上,生成Groovy代碼,實際上,主機是一個Grails應用程序)並將決策邏輯完全移入服務器。現在,JavaScript端簡單地解釋一個包含各個字段值的JSON對象。

最終,這可能會經歷一次更多的迭代,併成爲數據庫表中的數據,由位向量索引。

表驅動部分當然是出路;已經出現了半打新的改變了顯示的具體要求。

+2

從我瞭解你的問題,你的重構的想法是健全的,但TBH我我不確定您的描述是什麼,您需要什麼:P – 2011-01-12 21:45:16

+0

每一位都確定具體的行動嗎?如果是這樣,爲什麼不在你的值上對[0x01,0x02,0x04,0x08,0x10,0x20,0x40]執行按位AND操作 – draeton 2011-01-12 22:16:37

回答

1

您是否考慮過在服務器上生成決策樹,而不是用手寫出決策樹?使用任何表示都乾淨,易於使用和修改,然後編譯爲客戶端醜陋而高效的JavaScript。

決策樹可以很容易地表示爲數據,並且它很容易理解並作爲傳統的樹形數據結構進行處理。你可以以任何形式存儲所說的樹。驗證並修改它作爲數據也應該是直截了當的。

然後,當您需要使用決策樹時,只需將其編譯/序列化爲JavaScript,作爲一個大的if-else,switch或hash混亂。這應該也是相當直接的,並且可能比試圖用幾百個元素維護switch更容易。

2

由於情況(如您所描述的)非常不規則,似乎沒有更好的方法。雖然,我可以建議對跳轉表進行改進。你提到你有錯誤和重複。因此,可以將它們分配給指定的函數,而不是明確地將它們分配給閉包,以便不必重複顯式閉包。

var doAThingAndAnother = function(){ doAThing(); doAnotherThing(); } 

var tbl; // initialize it with the values 
    ... 
tbl[0x42] = doAThingAndAnother; 
tbl[0x43] = doAThingAndAnother; 

沒有太大的改進,但它是我能想到的唯一的東西!您似乎已經涵蓋了大部分其他問題。由於看起來需求變化非常大,我認爲你可能不得不放棄優雅,並且設計不夠優雅,但仍然容易改變。

5

我看到兩個選項...

兩者共同的解決方案有以下幾種命名功能:

function aThing() {} 
function anotherThing() {} 
function aThirdThing() {} 

開關方式

function exec(bits) { 
switch(bits) { 
    case 0x00: aThing(); anotherThing(); break; 
    case 0x01: aThing(); anotherThing(); aThirdThing(); break; 
    case 0x02: aThing(); aThirdThing(); break; 
    case 0x03: anotherThing(); aThirdThing(); break; 
    ... 
    case 0x42: aThirdThing(); break; 
    ... 
    case 0x7f: ... break; 
    default: throw 'There is only 128 options :P'; 
    } 
} 

地圖方式

function exec(bits) { 
    var actions = map[bits]; 
    for(var i=0, action; action=actions[i]; i++) 
     action(); 
} 

var map = { 
0x00: [aThing, anotherThing], 
0x01: [aThing, anotherThing, aThirdThing], 
0x02: [aThing, aThirdThing], 
0x03: [anotherThing, aThirdThing], 
    ... 
0x42: [aThirdThing], 
    ... 
}; 

在這兩種情況下,你會打電話

exec(0x42);