JS设计模式笔记(单例和策略)
单例模式
单例模式的核心是确保只有一个实例,并提供全局访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var getSingle = function(fn) { var result; return function() { return result || (result = fn.apply(this, arguments)); } };
var createLoginLayer = function() { var div = document.createElement('div'); div.innerHTML='我是登录框'; div.style.display = 'none'; document.body.appendChild(div); return div; };
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('test').onlick = function() { var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; };
|
创建实例对象的职责和管理单例的职责分别放置在2个方法里,这两个方法可以独立变化而互不影响
策略模式
策略模式的目的是将算法的使用和算法的实现分离
一个基于策略模式的程序至少有两部分组成.
- 一组策略类,策略类封装了具体的算法,并负责具体的计算过程
- 环境类Context, Context接受客户请求,随后把请求委托给某一策略类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
var strategies = { 'S': function(salary) { return salary * 4; }, 'A': function(salary) { return salary * 3; }, 'B': function(salary) { return salary * 2; } };
var calculateBonus = function(level, salary) { return strategies[level](salary); };
console.log(calculateBonus('S', 20000));
|
calculateBonus并没有计算奖金的能力,而是把这个职责委托给了某个策略对象,每个策略对象负责的算法已经被各自封装在对象内部了
策略模式也可以用来封装一系列”业务规则”.只要这些业务规则指向的目标一致,并且可以被替换使用,就可以使用策略模式封装它们;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
var strategies = { isNonEmpty: function(value, errMsg) { if (value === '' || value === undefined || value === null) { return errMsg; } }, minLen: function(value, len, errMsg) { if (value.length < len) { return errMsg; } } };
var Validator = function() { this.cache = []; };
Validator.prototype.add = function(value, rules) { var _this = this; for (var i = 0, rule; rule = rules[i]; i++) { (function(rule) { var strategyArr = rule.strategy.split(':'); var ruleName = strategyArr.shift(); strategyArr.unshift(value); strategyArr.push(rule.errMsg || (rule + '错误')); _this.cache.push(function() { return strategies[ruleName].apply(null, strategyArr); }); })(rule); } };
Validator.prototype.start = function() { for (var i = 0, validatorFun; validatorFun = this.cache[i]; i++) { var errMsg = validatorFun(); if (errMsg) { return errMsg; } } };
function checkreg(userName) { var validator = new Validator(); validator.add(userName, [{ strategy: 'isNonEmpty', errMsg: '用户名不能为空' }, { strategy: 'minLen:3', errMsg: '最小长度为3' }]); var errMsg = validator.start(); console.log(errMsg); }
checkreg(''); checkreg('aa');
|
策略模式的优点
- 策略模式利用 组合,委托和多态等技术和思想,可以有效的避免多重条件选择语句
- 策略模式提供了对开方-封闭原则的完美支持,将算法封装在独立的strategy中,使得他们易于切换,易于理解,易于扩展
- 策略模式的算法也可以复用在系统的其他地方,从而必选许多重复的复制粘贴工作
- 在策略模式中利用组合和委托来让Context拥有算法的执行能力,这也是继承的一种更轻便的替代方案
策略模式的缺点
- 增加了许多策略类/策略对象
- 必须了解所有的strategy,知道其不同点
参考文档
- 实体书:
JavaScript设计模式与开发实践(曾探)
文章若有纰漏请大家补充指正,谢谢~~
http://blog.xinshangshangxin.com SHANG殇