Javascript Patterns--读书笔记10 (Strategy)

Strategy模式允许你在运行的时候可以选择不同的算法。你的代码可以提供一个统一的接口,但是指定的任务可以根据不同的上下文来选择不同的算不了法。
来看一个用strategy模式来解决问题的例子:表单检查。你可以创建一个validate()方法。我们用这个方法来检验表单,而不管这个表单是什么类型的表单,我们所要得到的是一个正确的数据。
而真正我们需要实现的是,根据具体的form类型,可以选择不同的类型检查器来检查。你的validator将会选取最好的策略来处理这个task,然后用最合适的算法来检查。

Data Validation Example

下面的数据,来自一个页面,我们来检查一下它们的有效性:

var data =  {
    first_name: "Super",
    last_name: "Man",
    age: "unknown",
    username: "o_0"
}

对validator来说,什么是最好的策略对这个具体的实例,你必须首先配置这个validator并且设置一系列的规则来决定那些是有效的。
具体来说,你在做姓名检查时,不需要last_name,可以接受任意的字符做为fist_name,但是你需要年龄是Number, username只能包含字母和数字并且不能包含特殊的符号。我们可以列出下列的configuration:

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

现在validator对象已经配置好了,可以来处理上边的数据了,我们看一下如何来调用validate()

validator.validate(data);
if(validator.hasErrors()){
    console.log(validator.message.join("\n");
}

得到的结果将会是
Invalid value for *age*, the value can only be a valid number, e.g.1, 3.14 or 2010
Invalid value for *username*, the value can only contain characters and numbers, no special symbols
现在让我们来看一下如何实现这个validators.

实现

View Code
//check for non-empty values
validator.types.isNonEmpty = {
    validate: function(value) {
        return value !=="";
    },
    instructions: "the value cannot be empty"
};

//check if a value is a number
validator.types.isNumber = {
    validate: function(value){
        return !isNaN(value);
    },
    instructions: "the value can only be a valid number, e.g. 1, 3.14 or 2010"
};

//checks if the value contains only letters and numbers
validator.types.isAlphaNum = {
    validate: function(value) {
        return !/[^a-z0-9]/i.test(value);
    },
    instructions: "the value can only contain characters and numbers, no special symbols"
};

var validator ={
    //all available checks
    types: {},
    //error messages in teh current validation session
    messages: [],
    config: {},
    //the interface method
    validate: function(data) {
        var i, msg, type, checker, result_ok;
        //reset all messages
        this.messages = [];
        for( i in data) {
            if(data.hasOwnProperty(i)){
                type = this.config[i];
                checker = this.types[type];
                if(!type) {
                    continue;//no need to validate
                }
                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();
    },
    hasErrors: function() {
        return this.messages.length!==0;
    }
}

 

 

posted @ 2012-10-15 22:54  moonreplace  阅读(212)  评论(0编辑  收藏  举报