《Javascript设计模式与开发实践》关于设计模式典型代码的整理:单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式
1、单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
使用闭包封装私有变量
// 使用闭包创建单例
var user = (function () {
var _name = 'sven',
_age = 29;
return {
getUserInfo: function () {
return _name + '-' + _age;
}
}
})();
惰性单例(只在合适的时候创建对象,并且之创建唯一的一个,试用于dom重复生成、事件绑定等场景)
// 惰性单例生成
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
}
};
2、策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
// 策略模式
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));
console.log(calculateBonus('A', 10000));
3、代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。
// 虚拟代理
var myImage = (function () {
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
return {
setSrc: function (src) {
imgNode.src = src;
}
}
})();
var proxyImage = (function () {
var img = new Image;
img.onload = function () {
myImage.setSrc(this.src);
}
return {
setSrc: function (src) {
myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
img.src = src;
}
}
})();
// 测试
proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
// 缓存代理
var mult = function () {
console.log('开始计算乘积');
var a = 1;
for(var i = 0, l = arguments.length; i < l; i++) {
a = a * arguments[i];
}
return a;
}
var proxyMult = (function () {
var cache = {};
return function () {
var args = Array.prototype.join.call(arguments, ',');
if(args in cache) {
return cache[args];
}
return cache[args] = mult.apply(this, arguments);
}
})();
// 测试
proxyMult(1,2,3,4);
proxyMult(1,2,3,4);
4、迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
// 迭代器模式
var each = function(ary, callback) {
for (var i = 0, l = ary.length; i < l; i++) {
callback.call(ary[i], i, ary[i]);
}
};
// 测试
each([1, 2, 3], function(i, n) {
alert ([i, n]);
});
5、发布-订阅模式:它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。
// 发布-订阅模式
var event = {
clientList: [],
listen: function (key, fn) {
if (!this.clientList[key]) {
this.clientList[key] = [];
}
this.clientList[key].push(fn); // 订阅的消息添加进缓存列表
},
trigger: function () {
var key = Array.prototype.shift.call(arguments);
fns = this.clientList[key];
if (!fns || fns.length === 0) { // 如果没有绑定对应的消息
return false;
}
for (var i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments);
}
},
remove: function (key, fn) {
var fns = this.clientList[key];
if (!fns) { // 如果 key 对应的消息没有被人订阅,则直接返回
return false;
}
if (!fn) { // 如果没有传入具体的回调函数,表示需要取消 key 对应消息的所有订阅
fns && (fns.length = 0);
} else {
for (var l = fns.length - 1; l >= 0; l--) {
var _fn = fns[l];
if (_fn ===fn) {
fns.splice(l, 1); // 删除订阅者的回调函数
}
}
}
}
};
// 安装发布—订阅功能
var installEvent = function (obj) {
for (var i in event) {
obj[i] = event[i];
}
};
// 测试
var salesOffices = {};
installEvent( salesOffices );
salesOffices.listen( 'squareMeter88', fn1 = function( price ){
console.log( '价格= ' + price );
}); // 小明订阅消息
salesOffices.listen( 'squareMeter88', fn2 = function( price ){
console.log( '价格= ' + price );
}); // 小红订阅消息
salesOffices.remove( 'squareMeter88', fn1 );
salesOffices.trigger( 'squareMeter88', 2000000 ); // 输出:2000000
6、命令模式:用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。
// 命令模式
var bindClick = function (button, func) {
button.onclick = func;
};
var MenuBar = {
refresh: function () {
console.log('刷新菜单界面');
}
};
var SubMenu = {
add: function () {
console.log('增加子菜单');
},
del: function () {
console.log('删除子菜单');
}
};
// 测试
bindClick(button1, MenuBar.refresh);
bindClick(button2, SubMenu.add);
bindClick(button3, SubMenu.del);
7、组合模式:将对象组合成树形结构,以表示“部分-整体”的层次结构。
// 组合模式
var closeDoorCommand = {
execute: function () {
console.log('关门');
}
};
var openPcCommand = {
execute: function () {
console.log('开电脑');
}
};
var openQQCommand = {
execute: function () {
console.log('登录 QQ');
}
};
var MacroCommand = function () {
return {
commandsList: [],
add: function (command) {
this.commandsList.push(command);
},
execute: function () {
for (var i = 0, command; command = this.commandsList[i++];) {
command.execute();
}
}
}
};
// 测试
var macroCommand = MacroCommand();
macroCommand.add(closeDoorCommand);
macroCommand.add(openPcCommand);
macroCommand.add(openQQCommand);
macroCommand.execute();
转自:https://blog.csdn.net/QQsilhonette/article/details/84943932
《Javascript设计模式与开发实践》关于设计模式典型代码的整理:单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式的更多相关文章
- JavaScript设计模式与开发实践 - 观察者模式
概述 观察者模式又叫发布 - 订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- JavaScript设计模式与开发实践 - 策略模式
引言 本文摘自<JavaScript设计模式与开发实践> 在现实中,很多时候也有多种途径到达同一个目的地.比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但 ...
- JavaScript设计模式与开发实践 - 单例模式
引言 本文摘自<JavaScript设计模式与开发实践> 在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返 ...
- 《javascript设计模式与开发实践》--- (单一职责原则)
看的这本书叫<JavaScript设计模式与开发实践> 先规划一下看书的顺序,基础知识我已经大概的浏览了一遍了,没有留下笔记,以后有时间还会补上.本来打算顺着看的.但是我感觉我很难短时间内 ...
- JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)
说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...
- 《JavaScript设计模式与开发实践》读书笔记-基础知识
笔记内容多摘录自<JavaScript设计模式与开发实践>(曾探著),侵删. 面向对象的JavaScript 1. 动态需要类型和鸭子类型 鸭子类型 如果它走起路来像鸭子,叫起来也是鸭子, ...
- 《Javascript设计模式与开发实践》--读书笔记
第2章 this call apply bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用. bind( ...
- 《JavaScript设计模式与开发实践》知识点笔记
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...
- JavaScript设计模式与开发实践——JavaScript的多态
“多态”一词源于希腊文polymorphism,拆开来看是poly(复数)+ morph(形态)+ ism,从字面上我们可以理解为复数形态. 多态的实际含义是:同一操作作用于不同的对象上面,可以产生不 ...
随机推荐
- spring mvc 接受数组
@RequestParam(value = "customerIds[]")Integer[] customerIds 加上 requestParam value设置为 &qu ...
- MVC 源码系列之控制器执行(一)
控制器的执行 之前说了Controller的激活,现在看一个激活Controller之后控制器内部的主要实现. public interface IController { void Execute( ...
- vue猜数字游戏
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- linux 截取变量字符串
STR=123456abc FINAL=`echo ${STR: -1}` 或者 FINAL=${STR: -1} 都可以让FINAL获得c这个最后一个字符 Linux 的字符串截取很有用.有八种 ...
- Sentinel整合Dubbo限流实战(分布式限流)
之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...
- jdk与eclipse安装注意事项
1.安装这两个软件,一定要注意使得两个软件的版本是一致的: 1.1编写小程序测试jdk的版本号: public class Text{ public static void main(String[] ...
- Tornado 的核是什么??
Tornado 的核心是 ioloop 和 iostream 这两个模块,前者提供了一个高效的 I/O 事件循环,后 者则封装了 一个无阻塞的 socket .通过向 ioloop 中添加网络 I/O ...
- [书接上一回]在Oracle Enterprise Linux (v5.7) 中安装DB - (1/4)
在上一回中,我们安装了OEL了,现在就要安装Oracle数据. 首先登录root用户,输入账号密码或,输入命令行:startx,启动图形界面. 先将虚拟机中插入光碟(Enterprise-R5-U7- ...
- 全面优化MySQL(一)
mysql执行一条查询语句的内部执行过程 权限验证 客户端通过连接器连接到 MYSQL服务器. 查询缓存 查询是否有查询缓存, 如果有缓存(之前执行过此语句),则直接返回缓存数据. 语法检查 分析器会 ...
- Codeforces Round #421 (Div. 2) - A
题目链接:http://codeforces.com/contest/820/problem/A 题意:一个人在看一本书,书一共C页,这个人每天看v0页,但是他又开始加速看这本书,每天都比前一天多看a ...