策略模式
概念
定义一系列算法,把它们一个个封装起来。
将算法的使用与算法的实现分离开来
实现
// 加权映射关系 var levelMap = { S: 10, A: 8, B: 6, C: 4 }; // 组策略 var scoreLevel = { basicScore: 80, S: function() { return this.basicScore + levelMap['S']; }, A: function() { return this.basicScore + levelMap['A']; }, B: function() { return this.basicScore + levelMap['B']; }, C: function() { return this.basicScore + levelMap['C']; } } // 调用 function getScore(level) { return scoreLevel[level] ? scoreLevel[level]() : 0; } console.log( getScore('S'), getScore('A'), getScore('B'), getScore('C'), getScore('D') ); // 90 88 86 84 0
在组合业务规则方面,比较经典的是表单的验证方法。
// 错误提示 var errorMsgs = { default: '输入数据格式不正确', minLength: '输入数据长度不足', isNumber: '请输入数字', required: '内容不为空' }; // 规则集 var rules = { minLength: function(value, length, errorMsg) { if (value.length < length) { return errorMsg || errorMsgs['minLength'] } }, isNumber: function(value, errorMsg) { if (!/d+/.test(value)) { return errorMsg || errorMsgs['isNumber']; } }, required: function(value, errorMsg) { if (value === '') { return errorMsg || errorMsgs['required']; } } }; // 校验器 function Validator() { this.items = []; }; Validator.prototype = { constructor: Validator, // 添加校验规则 add: function(value, rule, errorMsg) { var arg = [value]; if (rule.indexOf('minLength') !== -1) { var temp = rule.split(':'); arg.push(temp[1]); rule = temp[0]; } arg.push(errorMsg); this.items.push(function() { // 进行校验 return rules[rule].apply(this, arg); }); }, // 开始校验 start: function() { for (var i = 0; i < this.items.length; ++i) { var ret = this.items[i](); if (ret) { console.log(ret); // return ret; } } } }; // 测试数据 function testTel(val) { return val; } var validate = new Validator(); validate.add(testTel('ccc'), 'isNumber', '只能为数字'); // 只能为数字 validate.add(testTel(''), 'required'); // 内容不为空 validate.add(testTel('123'), 'minLength:5', '最少5位'); // 最少5位 validate.add(testTel('12345'), 'minLength:5', '最少5位'); var ret = validate.start(); console.log(ret);
优缺点
优点:可以有效地避免多重条件语句,将一系列方法封装起来也更直观,利于维护
缺点:往往策略集会比较多,要事先就了解定义好所有的情况