JavaScriptシリーズを深く理解する(33):設計モードのポリシーモードの詳細

4882 ワード

紹介する
ポリシー・モードは、アルゴリズム・ファミリーを定義し、それぞれカプセル化して、アルゴリズムの変化がアルゴリズムを使用するお客様に影響を与えないようにします.
本文
ポリシー・モードを理解する前に、まず例を挙げます.一般的に、データの合法性の検証を行うには、swith文に従って判断することが多いですが、これはいくつかの問題をもたらします.まず、需要が増加すれば、このコードを再修正して論理を増加させ、ユニットテストを行うときもますます複雑になります.コードは次のとおりです.
 
  
        validator = {
            validate: function (value, type) {
                switch (type) {
                    case 'isNonEmpty ':
                        {
                            return true; // NonEmpty
                        }
                    case 'isNumber ':
                        {
                            return true; // Number
                            break;
                        }
                    case 'isAlphaNum ':
                        {
                            return true; // AlphaNum
                        }
                    default:
                        {
                            return true;
                        }
                }
            }
        };
        // 
        alert(validator.validate("123", "isNonEmpty"));

では、上記のコードの問題を回避するにはどうすればいいのでしょうか.ポリシーモードによって、同じ作業コードを個別に異なるクラスにカプセル化し、統一されたポリシー処理クラスで処理することができます.OK、まずポリシー処理クラスを定義します.コードは以下の通りです.
 
  
var validator = {

    // ,
    types: {},

    //
    messages: [],

    //
    config: {},

    //
    // key => value
    validate: function (data) {

        var i, msg, type, checker, result_ok;

        //
        this.messages = [];

        for (i in data) {
            if (data.hasOwnProperty(i)) {

                type = this.config[i];  // key
                checker = this.types[type]; //

                if (!type) {
                    continue; // ,
                }
                if (!checker) { // ,
                    throw {
                        name: "ValidationError",
                        message: "No handler to validate type " + type
                    };
                }

                result_ok = checker.validate(data[i]); //
                if (!result_ok) {
                    msg = "Invalid value for *" + i + "*, " + checker.instructions;
                    this.messages.push(msg);
                }
            }
        }
        return this.hasErrors();
    },

    // helper
    hasErrors: function () {
        return this.messages.length !== 0;
    }
};


残りの作業はtypesに格納されている様々な検証クラスを定義することです.ここではいくつかの例を挙げます.
 
  
//
validator.types.isNonEmpty = {
    validate: function (value) {
        return value !== "";
    },
    instructions: " "
};

//
validator.types.isNumber = {
    validate: function (value) {
        return !isNaN(value);
    },
    instructions: " , :1, 3.14 or 2010"
};

//
validator.types.isAlphaNum = {
    validate: function (value) {
        return !/[^a-z0-9]/i.test(value);
    },
    instructions: " , "
};


使用する場合は、まず検証が必要なデータセットを定義し、次に、各データの検証が必要なルールタイプを定義する必要があります.コードは次のとおりです.
 
  
var data = {
    first_name: "Tom",
    last_name: "Xu",
    age: "unknown",
    username: "TomXu"
};

validator.config = {
    first_name: 'isNonEmpty',
    age: 'isNumber',
    username: 'isAlphaNum'
};


最後に、検証結果のコードを取得するのは簡単です.
 
  
validator.validate(data);

if (validator.hasErrors()) {
    console.log(validator.messages.join("
"));
}


まとめ
ポリシーモードは一連のアルゴリズムを定義し、概念的に言えば、これらのアルゴリズムはすべて同じことをしているが、異なることを実現するだけで、彼は同じ方法ですべての方法を呼び出すことができ、各種のアルゴリズムクラスと使用アルゴリズムクラスの間の結合を減らすことができる.
別のレベルでは、アルゴリズムクラスを個別に定義することで、独自のアルゴリズムで個別のテストを行うことができるため、ユニットテストも容易になります.
実際には、アルゴリズムをカプセル化するだけでなく、ほとんどのタイプのルールをカプセル化するためにも使用できます.分析の過程で異なるビジネスルールを異なる時間に適用する必要があるため、ポリシーモデルが様々な変化を処理することを考慮することができます.