JS设计模式1 - 基本概念和单列
最近在看Vue源码,但是觉得先阅读这么大的工程前应该先复习一下基础知识,比如设计模式,TypeScript等。所以准备网上搜索一下,在此总结总结。
什么是设计模式
A pattern is a reusable solution that can be applied to commonly occurring problems in software design
模式是针对经常出现的“软件设计问题”的“可复用”的解决方案。
设计模式有什么好处
- 模式是已经验证过的解决方案
- 模式复用起来比较简单,有成熟的方法。
- 模式可以表达复杂的软件设计思想
设计模式的组成部分
这里给的不是标准,但是是我觉得的必要部分
- 结构图
- 目的
- 何时使用
- 已知的常用场景
设计模式的分类
- 创建型:用来创建对象,和实现解耦。
- 结构型:用来把不相关的对象组成一个大的对象
- 行为型:管理算法,对象间的关系和职责。
另外还有一种分类方式
- 对象型:处理对象间 "在运行时可以改变的" 关系
- 类型:处理类之间的关系(此分类对于JS来说没用)
![](https://img.haomeiwen.com/i1616121/79eb02c7c0f231bd.png)
热身
文章1就先热身一下吧。
单列模式
![](https://img.haomeiwen.com/i1616121/39b4c37ddc14b325.png)
目的
确保系统中只有一个类的实例。
何时使用
- 主需要一个实例
- 控制对一个对象的访问
常见使用场景
许多语言提供系统对象或者坏境对象,允许语言访问底层操作系统。因为应用在物理上运行于一个操作系统,所以只需要一个环境的实例。单列模式由语言的运行时环境实现保证只有一个系统实例并且保证合适的访问权限。
在js中比如window对象,node中的process对象都是单列的。
代码实现
var mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
// Private methods and variables
function privateMethod(){
console.log( "I am private" );
}
var privateVariable = "Im also private";
var privateRandomNumber = Math.random();
return {
// Public methods and variables
publicMethod: function () {
console.log( "The public can see me!" );
},
publicProperty: "I am also public",
getRandomNumber: function() {
return privateRandomNumber;
}
};
};
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {
if ( !instance ) {
instance = init();
}
return instance;
}
};
})();
var myBadSingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
var privateRandomNumber = Math.random();
return {
getRandomNumber: function() {
return privateRandomNumber;
}
};
};
return {
// Always create a new Singleton instance
getInstance: function () {
instance = init();
return instance;
}
};
})();
// Usage:
var singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); // true
var badSingleA = myBadSingleton.getInstance();
var badSingleB = myBadSingleton.getInstance();
console.log( badSingleA.getRandomNumber() !== badSingleB.getRandomNumber() ); // true
// Note: as we are working with random numbers, there is a
// mathematical possibility both numbers will be the same,
// however unlikely. The above example should otherwise still
// be valid.
上面代码可以在此下载:
https://github.com/benhaben/essentialjsdesignpatterns.git
注意点
-
myBadSingleton
是错误的做法。
the node way
因为node的模块机制保证所有引用的模块都是共享的,所以实现单列模式就更简单了
/*
* a-singleton.js
*/
// Private
var x = require('x');
var y = 'I am private';
var z = true;
function sum(num1, num2) {
return num1 + num2;
}
// Public
var self = module.exports = {
someProperty: 'I am public',
addFive: function addFive(num) {
return sum(num, 5);
},
toggleZ: function toggleZ() {
return z = !z;
}
};
/*
* app.js
*/
var singleton = require('./a-singleton');
console.log(singleton.x); // undefined (x is private)
console.log(singleton.sum(1,2)); // undefined (sum is private)
console.log(singleton.someProperty); // 'I am public'
console.log(singleton.toggleZ()); // false
console.log(singleton.toggleZ()); // true (public functions can still reference private variables)
总结
由于js没有多线程的问题,所以不需要锁,单列模式变得简单了。js也没有静态变量,类,所以也没有延迟创建等问题,总之,js的单线程特效使开发变得简单了。
参考资料
https://github.com/addyosmani/essential-js-design-patterns
https://addyosmani.com/resources/essentialjsdesignpatterns/book/
http://fredkschott.com/post/2013/12/node-js-cookbook---designing-singletons/