设计模式——之单例模式(高性能创建对象方法)
(本系列blog仅针对前端设计模式)
首先介绍一下设计模式:
1、设计模式最先被后端引入使用,由于javascript执行机制对设计模式并不是很友好,所以开发中也是根据需求选择相应的设计模式进行开发;
设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结;(设计模式可以说是一套开发经验,开发前应该想好自己代码采用哪些设计模式,为后期维护、开发做准备)
2、设计模式的六大原则:
①单一职责原则:一个函数尽量执行一个功能;(更好维护,更不容易出错)
②里氏代换原则:构造函数中可以定义一些方法,但是不实现具体的功能,只作为接口使用,让继承他的子类来实现具体的功能;
③依赖倒置原则DIP:最常用的原则。很多功能我们更希望得到接口,直接调用接口就可实现功能,而不想知道其具体的实现方法;
④接口分离原则ISP:把大的接口拆分成小的接口,防止大的接口挂掉后,影响过大;
⑤迪米特法则LD(最小知道原则):一个接口或者一个方法出入的参数越少越好;
⑥开闭原则OCP:面向扩展开放,面向修改关闭(jquery extend 等库,可用可扩展,不可更改方法);
单例模式——深入浅出
我们知道,每一个构造函数都会产生不同的对象,他们之间互不影响;开发中会创建很多对象,很多对象功能,样式完全一样,但是经常的创建,删除非常浪费性能,而使用单例模式创建的对象其实就是一个一样的对象,可以有效地节约空间,性能;
定义:保证一个类(构造函数)仅有一个实例,并提供一个访问它的全局访问点;
//单例模式的实现:
//实现思想:每次创建对象时,判断是不是第一次使用该构造函数创建对象,如果不是就将第一次创建的对象返回;
//方法一:
function Test (name) {
//var this = Object.creat(Test.prototype);
if(typeof Test.instance === 'object') {
return Test.instance;
}
this.name = name;
Test.instance = this;
//return this;
}
var a = new Test('one');
// Test.instance = 123; //外部修改后instance会变为非单例模式;
var b = new Test('two');
console.log(a === b); //结果为true,使构造函数每次构造出来的都是不是单独个体;
//但该方法不可行,因为instance暴露在全局,随便一修改就会是false;
//方法二:
function Test2 (name) {
var instance = this;
// console.log(this);
this.name = name;
Test2 = function (){
return instance
}
}
var e = new Test2();
Test2.instance = 123;
Test2.prototype.lastName = 111;
var f = new Test2();
console.log(e === f, e.lastNmae, f.lastName);
//虽然instance这回指向Test2{},但是该方法已经将Test2变为function,
//之后每次通过Test2构造出的函数,都会返回Test2{},无法使用原型上的方法;(不好)
//方法三:
var Test1 = (function (){
var instance;
return function (name) {
if(typeof instance === 'object') {
return instance;
}
this.name = name;
// console.log(this, instance, typeof instance);
instance = this; //让instance指向对象;
// console.log(this, instance, typeof instance);
}
})()
var c = new Test1(1);
Test1.prototype.lastName = 222;
Test1.instance = 123;
// console.log(Test1.instance);
var d = new Test1(2);
console.log(c === d, c.lastName, d.lastName); //结果仍为true,并且可以使用原型上新增的方法;
三种方法输出结果如下:
我们现在已经可以将一个构造函数完美的变为一个单例模式;那么如何将一个非单例模式的构造函数变为单例模式呢?
//功能:传一个函数,返回一个新的函数,并且该函数为单例模式:
var getSingle = function (func){
var result;
return function () {
if (!result) {
result = func.apply(this, arguments);
}
return result;
}
}
之后我会通过具体的demo来将单例模式应用到实战开发中;