继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

细品 javascript 设计模式(单利模式)

不羁的豆角
关注TA
已关注
手记 19
粉丝 15
获赞 33

我尽量用最少的文字,最少的篇幅,讲明白设计模式的方方面面。
文章连接

理解单利模式

确保只有一个实例,并提供全局访问。
例如 redux 中的 store,线程池,全局缓存,浏览器 window 对象等。

上代码:通用的惰性单利模式

let getSingle = function(fn) {
    let result = 'initial_single';
    return function() {
        if (result === 'initial_single') {
            result = fn.apply(this, arguments);
        }
        return result;
    }
}

// 测试 -----
let Tree = function() {
    console.log('something')
}
let getSingleTree = getSingle(Tree)
getSingleTree() // 第一次调用时输出:console.log('something')
getSingleTree() //
getSingleTree() //

// 调用三次只会输出一次

单利模式的演进过程

1. 普通单利

用变量来标记某个对象是否被创建过,如果是直接返回之前创建的变量

上代码:

let Person = function(name) {
    this.name = name
}
Person.prototype.getName = function() {
    console.log(this.name)
}
Person.getSingle = (function() {
    let instance = null;
    return function(name) {
        if (!instance) {
            instance = new Person(name)
        }
        return instance
    }
})();

2. 透明单利

有一个类,不论你 new 多少次。它都给你返回第一次 new 的那个实例。这就是透明的单利模式,所谓透明,就是你不能看出它是单利。

上代码:

let Person = (function() {
    let instance;
    Person = function(name) {
        if (instance) {
            return instance;
        }
        this.name = name;
        return instance = this;
    }
    return Person;
})();
let p = new Person('C#')
let a = new Person('java')
console.log(p === a) // true

3. 用代理实现单利

之前的单利实现都有一个共同的问题:类和单利的代码都交织在一起。这样有违反“单一职能”原则。

代理,就是把类应该做的事,和单利应该做的事情分开
上代码:

// 类
var Person = function(name) {
    this.name = name;
}
// 代理
let ProxySinglePerson = (function() {
    let result;
    return function(name) {
        if (result) {
            return result
        }
        result = new Person(name)
        return result
    }
})();

let p = new ProxySinglePerson('C#')
let a = new ProxySinglePerson('java')
console.log(p === a) // true

5. 惰性单利

意思是,需要用到的时候才创建。这是单利模式的应用中非常重要的一点。
其实之前的代码中也已经包含了惰性单利,看下面代码。重点关注“惰性”。

上代码:

// 类
var Person = function(name) {
    this.name = name;
}
Person.getSingle = (function() {
    let instance;
    return function(name) {
        if (!instance) {
            instance = new Person(name);
        }
        return instance;
    }
})();
var p = Person.getSingle('C#')
var a = Person.getSingle('java')
console.log(p === a) // true

6. 通用的惰性单利

一劳永逸,这次咱们完成一个通用的惰性单利。也就是文章开头的那段代码
let getSingle = function(fn) {
    let result = 'initial_single';
    return function() {
        if (result === 'initial_single') {
            result = fn.apply(this, arguments);
        }
        return result;
    }
}

小结

本章学习了单利模式的演进过程,还提到了代理模式和单一职责原则。之后的文章里我会对他们做详细的讲解。

在 getSingle 函数中,也提到了闭包和高阶函数的概念。单利模式是一种非常实用的模式,特别是惰性单利技术,在合适的时候才创建对象,并且全局唯一。更奇妙的是创建对象和管理单利的职责被分布在两个不同的方法中,这两个方法组合起来才有单利模式的威力。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP