码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript 设计模式

时间:2020-02-24 21:01:49      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:系统   设计   spi   ini   重用   inner   init   child   结构   

JavaScript 设计模式

  • 一个模式就是一个可重用的方案。当代码是建立在行之有效的模式上时,我们可以花更少的时间去关心我们的代码结构,从而能花更多的时间关注我们的解决方案的整体质量。

  • 本文将简略通俗地,向大家说明常见的三大 JavaScript 设计模式:单例模式、组合模式、观察者模式

单例模式 Singleton

  • 单例模式:限制一个类只能有一个实例化对象

    • 也就是说,一个构造函数一生只能有一个实例化对象。

    • 就像二胎政策之前的计划生育一样,夫妻双方(构造函数)一生只能有一个孩子(实例化对象)

var Parents = (function () {
    // 夫妻双方(构造函数)
    function Parents() {
        this.date = ‘出生时间:‘ + new Date();
        this.father = ‘父亲:XXX‘;
        this.mather = ‘母亲:XXX‘;
        this.palce = ‘出生地:XXX‘;
    }
    Parents.prototype.hospital = function () {};

    var instance = null;
    function singleton() {
        if (!instance) {
            //如果没有实例化一个对象的话,就实例一个new Parents()
            instance = new Parents();
        }
        
        return instance
    }
    //如果已经实例化一个对象的话,直接返回之前已经实例化的对象
    return singleton
})()
//实例化对象
var child1 = new Parents() // 相当于在执行 singleton 函数, 第一次的时候会得到一个 Parents 的实例
var child2 = new Parents() // 相当于在执行 singleton 函数, 第二次的时候, 依旧得到第一次的实例
console.log(child1 === child2) // true也就是两次实例化对象都指向同一个地址

组合模式 Composite

  • 组合模式:又叫 “部分整体” 模式,将对象组合成树形结构,以表示 “部分-整体” 的层次结构。用包含多个部件的对象组合成单一实体,这个单一实体将用作所有这些部件的访问点

    • 平时我们在使用计算机的时候就经常遇见组合模式,当删除计算机中某个文件夹的时候,也就意味着会删除该文件夹内的所有内容。通过操作删除文件夹(单一实体)的步骤,你就能达到想要删除该文件夹内的所有内容(多个部件的对象)的目的

// 多个部件的对象
// 第一个构造函数
class Play {
    constructor(){};
    init(){
        console.log(‘game begin‘);
        this.gameA();
        this.gameB();
        this.gameC();
    };
    gameA(){};
    gameB(){};
    gameC(){};
}
// 第二个构造函数
class Eat{
    constructor(){};
    init(){
        console.log(‘eat dinner‘);
    }
}
// 第三个构造函数
class Sleep{
    constructor(){};
    init(){
        console.log(‘go to sleep‘);
    }
}
// 单一实体
class Compose{
    constructor(){
        // 用来承载每一个实例的数组
        this.composeArr=[];
    }
    add(instance){
        //多个部件的对象 放入 单一实体
        this.composeArr.push(instance);
    }
    
    init(){
        //console.log(‘执行单一实体‘);
        // 把数组里面的每一个内容调用了
        this.composeArr.forEach(item => item.init())
    }
}
let oCompose = new Compose();
// 每一次执行 add 方法就是向 oCompose 上添加内容
oCompose.add(new Play());
oCompose.add(new Eat());
oCompose.add(new Sleep());
// oCompose 里面的每一个构造函数就同时调用了
oCompose.init();
console.log(oCompose);

发布/订阅模式 Publish / Subscribe

  • 发布/订阅 模式:系统中的对象可以在关注的事件发生的时候给其他对象发送消息,也可以被其他对象所通知。多用于注册和接受由发布者广播的相关通知。

    • 发布/订阅 角度,分成三个状态:订阅,取消订阅,发布

    • 简单来说就是我们平时玩的微博:关注博主(订阅),取消关注(取消订阅),关注博主的用户收到博主发布新微博的提醒(发布)

class Observer {
    constructor () {
        // 准备的一个微信公众号
        this.message = {}
    }

    // 关注公众号(订阅)
    on (type, fn) {
        // 向消息盒子里面添加成员
        // type 事件类型(你要订阅的类型)
        // fn 事件处理函数(你要给这个类型订阅一个什么行为)
        if (!this.message[type]) {
            // 表示 this.message 里面没有这个成员
            this.message[type] = []
        }

        this.message[type].push(fn)
    }

    // 取消关注公众号(取消订阅)
    off (type, fn) {
        // 删除消息盒子里面的某一个成员
        // type 是你要取消的事件类型
        // fn 是你要取消的事件处理函数
        if (!this.message[type]) return
        // 能执行到这里, 表示 this.message[type] 是一个数组
        // 取消这个数组里面和 fn 一样的那个事件处理函数
        //   使用过滤器 filter 方法
        this.message[type] = this.message[type].filter(item => item !== fn)
    }

    // 微信粉丝发布的信息
    emit (type, ...arg) {
        // 执行消息盒子里面的某一个对应的处理函数
        // type 就是你要触发的事件类型
        // 判断你有没有订阅过, 如果没有订阅过, 直接return
        if (!this.message[type]) return
        // console.log(arg)
        // arg 是发布的文章 
        var event = {
            // 文章标题
            data: arg
        }
        // 调用每一个事件处理函数的时候, 都给你带上一个事件对象
        // 如果你订阅过, 那么就执行一下
        this.message[type].forEach(item => item(event))
    }
}

var o = new Observer()

// 粉丝 A B C D E 订阅公众号
o.on(‘click‘, handlerA)
o.on(‘click‘, handlerB)
o.on(‘click‘, handlerC)
o.on(‘click‘, handlerD)
o.on(‘click‘, handlerE)

// 粉丝 A 取消订阅
o.off(‘click‘, handlerA)

// 公众号发布文章,粉丝 B C D E 收到
o.emit(‘click‘, ‘文章一‘,‘文章二‘,‘文章三‘)
// 发布事件
// 把你订阅好的事件处理函数都给你触发了
// console.log(o)

// 粉丝 A B C D E 
// e 接收公众号发布的文章
function handlerA(e) { console.log(‘粉丝A‘, e) }
function handlerB(e) { console.log(‘粉丝B‘, e) }
function handlerC(e) { console.log(‘粉丝C‘, e) }
function handlerD(e) { console.log(‘粉丝D‘, e) }
function handlerE(e) { console.log(‘粉丝E‘, e) }

 

 

JavaScript 设计模式

标签:系统   设计   spi   ini   重用   inner   init   child   结构   

原文地址:https://www.cnblogs.com/Welin/p/12345452.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!