我在面向文檔的前面添加了一個安全層,我需要一種合理的抽象方式來定義應用程序定義哪些新文檔以及現有文檔的哪些更新對特定用戶是合法的。好的,是* this * monadic?
特定問題是 - 文檔被定義(至少在傳輸中)爲JSON對象,所以規則可能是分層的,因此規則引擎必須遞歸地工作。例如,Employee對象可能有一個名爲Compensation的子對象,並且該子對象有一個名爲PayPeriod的字段,該字段必須是「每週」,「雙週」或「每月」之一。 - 它運行Node.js,一些規則需要從輸入中讀取(例如,從數據庫中讀取更多用戶數據),因此它必須以連續方式運行。
所以我想到的是:每個規則是一個函數,它接受當前值,建議的新值以及與要使用的值一起調用的回調函數。該值可以是規則計算的兩個輸入值或第三個值中的一個。以下是一條規則:
var nonEmpty = function(proposedValue, existingValue, callback) {
callback((proposedValue.length > 0) ? proposedValue : existingValue);
};
此規則只允許您設置或用非零長度值替換此字段。當然,這僅是有道理的字符串值(暫時忽略列表,所以我們需要一個規則來執行字符串岬):
var isString = function(proposedValue, existingValue, callback) {
callback((typeof(proposedValue) === 'string') ? proposedValue : existingValue);
};
事實上,這似乎是問題一個不同凡響的,所以我寫了一個規則生成:
var ofType = function(typeName) {
return function(proposedValue, existingValue, callback) {
callback((typeof(proposedValue) === typeName) ? proposedValue : existingValue);
};
};
var isString = ofType('string')
,但我需要一種方法來串在一起的規則:
var and = function(f1, f2) {
return function(proposedValue, existingValue, callback) {
f1(proposedValue, existingValue,
function(newProposedValue) {
f2(newProposedValue, existingValue, callback);
});
};
};
var nonEmptyString = and(isString, nonEmpty);
所以對於一個管理員聯繫,以更新員工記錄的規則可能是:
limitedObject({
lastName : nonEmptyString,
firstName : nonEmptyString,
compensation : limitedObject({
payPeriod : oneOf('weekly', 'biweekly', 'monthly'),
pay : numeric
}
})
limitedObject
(如ofType
)是規則的生成函數,並且它僅允許在其參數指定的字段並施加給定的規則對這些字段的值。
所以我寫了所有這些,它就像一個魅力。我所有的錯誤都是單元測試中的錯誤!好吧,幾乎所有的人。無論如何,如果你已經讀了這麼多,這裏是我的問題:
我一直熱情地學習單子,我的閱讀激發了我用這種方式解決問題。但是,這是真正的一元嗎?
(可能的答案:「是的」,「不,但是沒關係,因爲單子不是真正解決這個問題的正確方法」,「不,這是需要改變的地方」。
* combinators * - 這是我正在尋找的模式的名稱。它感到非常熟悉。 – Malvolio
這是我見過的關於Javascript開發者的monad法則中最容易實現的完美! – rand