曾经,我非常羡慕那些人见人爱的人,我也想要变成那样,可是后来我才明白人见人爱也是需要天赋的,后来我开始默默努力,我想,就算我不能让每个人都喜欢我,至少因为我做的努力能得到别人的尊重。

JavaScript设计模式(三) - 策略模式

 

什么是策略模式? 

     策略模式支持在运行时由使用者选择合适的算法,对于使用者而言不用关心背后的具体实现,由使用者自动根据当前程序执行的上下文和配置,从已有的算法列列表中选择出合适的算法来处理当前任务。

  

 上面的两个例子就是策略模式,比如根据选择的刷子的种类不同,我们可以刷出不同样式的线条出来,但是各种刷子背后的实现机制我们并不需要关心,我们只需要关心当前图中需要应用哪种刷子可以完成任务。 商品类似。

 

 

为什么要使用策略模式?

  通过使用策略模式,我们可以很好地解决调用和需要调用的算法的耦合、增强可扩展性、可维护性等。 

  

 

如何实现策略模式? 

  对于策略模式,最为常用的场景就是 --- 表单验证

  通常对于一个表单,各个字段的输入值可能格式不一,电话号码、密码、邮箱,使用数字、字符等等,多个字段还要验证非空,一般而言,我们的实现方式可能是十几个甚至几十、上百个if、else,但是这样看上去验证函数会非常冗余。 这时,我们可以吧常见的验证策略抽象为一个策略集合,使用者需要对表单数据进行校验时,只需要传入数据以及指定各个字段的验证策略,就可以给出相应的验证结果了。 

  我们期望这样的调用:

// 待校验的数据
var data = {
    name: ' 王 x',
    gender: 1,
    identity: '011110198806061234',
    birthday: '1988-13-01',
    mobile: '15800000000',
    spareMobile: '13911111111',
    email: 'abcdef.cn'
};

// 校验规则配置
validator.config = {
    name: {
        text: ' 姓名 ',
        validators: ['isNotEmpty', 'isValidName']
    },
    identity: {
        text: ' 身份证号 ',
        validators: ['isNotEmpty','isValidIdentity']
    },
    birthday: {
        text: ' 生日 ',
        validators: [['isBirthEqualTo','identity'],'isValidDate']
    },
    mobile: {
        text: ' 手机号码 ',
        validators: ['isValidMobile']
    },
    spareMobile: {
        text: ' 备用手机号码 ',
        validators: ['isValidMobile', ['isNotEqualTo', 'mobile']]
    },
    email: {
        text: 'Email',
        validators: ['isValidEmail']
    }
};

// 调用获得校验结果
validator.validate(data);
if(validator.hasErrors()){
    validator.messages.join('<br/>');
}
// 期望结果:
/*
姓名只能为 2-4 个字的汉字
生日与身份证号不一致,请修改
生日格式不合法,请按 "2008-01-01" 格式输入日期
备用手机号码不得与手机号码相同,请重新输入
Email 格式不合法,请输入正确的 Email 地址
*/

 

  那么,下面我们就看看如何实现这样的validator对象 ---  针对每种校验策略,我们需要指定校验方法和校验失败时的错误提示,这些策略可以挂载到validator对象内部方便管理: 

  

// 所有可用的校验
validator.types = {

    isNotEmpty: {
        validate: function(value){
            return value !== "";
        },
        message: " 不得为空 "
    },

    isNotEqualTo: {
        validate: function(data, curField, compareField){
            return data[curField] === data[compareField];
        },
        message: function(fieldText){
            return " 不得与 " + fieldText + " 相同,请重新输入 ";
        }
    },

    isValidName: {
        validate: function(value){
            return /^[\u4e00-\u9fa5]{2,4}$/.test(value);
        },
        message: " 只能为 2-4 个字的汉字 "
    },

    ...

};

 

这样,以后,每次出现了需要验证的新的策略,我们就只需要将之添加到validator.types下面,然后在validator.config中添加校验规则,代码其他部分就不需要再进行调整了,依然执行validator.validate方法。 

 

posted @ 2017-08-22 16:08  Wayne-Zhu  阅读(442)  评论(0编辑  收藏  举报

一分耕耘,一分收获。