JS设计模式

Javascript的设计模式

设计模式基本可以分为三组模式:

  • 创建型模式:设计对象的创建与初始化
  • 结构型模式:描述了如何组合对象以提供新的功能
  • 行为型模式:描述了对象之间如何通信

本次主要讲解四个模式,即:

  • 单件模式
  • 工厂模式
  • 装饰器模式
  • 观察者模式

一、单件模式

1.单件模式1

最简单的单件模式就是利用对象文本标识法:

var single = {};

2.单件模式2

① 利用全局变量:

function Logger () {
    if (typeof global_log === "undefined") {
        global_log = this;
    }
    return global_log;
}
// 定义两个构造器,并比较
var a = new Logger();
var b = new Logger();
console.log(a === b); // true

② 利用构造器属性

function Logger () {
    if (!Logger.single_instance) {
        Logger.single_instance = this;
    }
    return Logger.single_instance;
}

③ 使用私有属性

var Logger = (function () {
    var private = this;
    return function () {
        return private;
    }
})()

二、工厂模式

当我们有多个相似的对象而又不知道应该使用哪一种的时候,
可以考虑使用工厂模式,根据输入自行决定创建哪一种对象

var myApp = {};
myApp.dom = {};
myApp.dom.Text = function (url) {
    this.url = url;
    this.insert = function (where) {
        var txt = document.createTextNode(this.url);
        where.appendChild(txt);
    };
};

myApp.dom.Link = function (url) {
    this.url = url;
    this.insert = function (where) {
        var link = document.createElement('a');
        link.href = this.url;
        link.appendChild(document.createTextNode(this.url));
        where.appendChild(link);
    };
};

myApp.dom.Image = function (url) {
    this.url = url;
    this.insert = function (where) {
        var im = document.createElement('img');
        im.src = this.url;
        where.appendChild(im);
    };
};

var url = 'http://www.baidu.com/logo.jpg';

var o = new myApp.dom.Image(url);
o.insert(document.body);

var o = new myApp.dom.Text(url);
o.insert(document.body);

var o = new myApp.dom.Link(url);
o.insert(document.body);

当我们写一个库或者框架时,可以考虑委托给一个工厂函数:

myApp.dom.factory = function (type, url) {
    return new myApp.dom[type](url);
};
var url = 'http://...'
var image = myApp.dom.factory("image", url);
image.insert(document.body);

三、装饰器模式

装饰器模式是一种结构型模式,它与对象创建无关,主要考虑的是如何拓展对象的功能。也就是说,除了使用线性式(父-子-孙)继承方式之外,我们也可以为一个基础对象创建若干个装饰对象以拓展其功能。

以下为具体实例:

var tree = {};
tree.decorate = function () {
    alert('Make sure the tree won\'t fall');
};

// getDecorate函数会创建一个原型为tree的新实例
tree.getDecorate = function (deco) {
    tree[deco].prototype = this;
    return new tree[deco];
};

tree.RedBalls = function () {
    this.decorate = function () {
        this.RedBalls.prototype.decorate();
        alert('Put on some red balls');
    };
};

tree.BlueBalls = function () {
    this.decorate = function () {
        this.BlueBalls.prototype.decorate();
        alert('Add blue balls');
    };
};

tree.Angel = function () {
    this.decorate = function () {
        this.Angel.prototype.decorate();
        alert('An angel on the top');
    };
};

// 把所有装饰器添加到基础对象中
tree = tree.getDecorate('BlueBalls');
tree = tree.getDecorate('RedBalls');
tree = tree.getDecorate('Angel');

// 运行decorate()
tree.decorate();//按顺序弹出4个提示

四、观察者模式

观察者模式(也成为发布-订阅模式)是一种行为型模式,主要用于处理不同对象之间的交互通信问题。

观察者模式中通常会包含两类对象:

  • 一个或多个发布者对象:当有重要的事情发生时,会通知订阅者。
  • 一个或多个订阅者对象:它们追随一个或多个发布者,监听他们的通知,并作出相应的反应

观察者对象应该有如下的属性和方法:

  • 由回调函数构成的订阅者数组
  • 用于添加和删除订阅者的addSubscriber()和removeSubscriber()方法。
  • publish()方法,接受并传递数据给订阅者。
  • make()方法,讲任意对象转变为一个发布者并为其添加上述方法。

以下是一个实现代码:

var observer = {
    // 添加订阅者
    addSubscriber: function (callback) {
        if (typeof callback === 'function') {
            this.subscribers[this.subscribers.length] = callback;
        }
    },
    // 删除订阅者
    removeSubscriber: function (callback) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (this.subscribers[i] === callback) {
                delete this.subscribers[i];
            }
        }
    },
    // 发布消息,出发回调函数
    publish: function (what) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (typeof this.subscribers[i] === 'function') {
                this.subscribers[i](what);
            }
        }
    },
    // 创建发布者
    make: function (o) {
        for (var i in this) {
            if (this.hasOwnProperty(i)) {
                o[i] = this[i];
                o.subscribers = [];
            }
        }
    }
}

// 创建两个发布者
var blogger = {
    writeBlogPost: function () {
        var content = 'Today is ' + new Date();
        this.publish(content);
    }
};
var la_times = {
    newIssue: function () {
        var paper = 'Martians have landed on Earth!';
        this.publish(paper);
    }
};
observer.make(blogger);
observer.make(la_times);

// 创建两个订阅者
var jack = {
    read: function (what) {
        console.log("I just read that " + what);
    }
};
var jill = {
    gossip: function (what) {
        console.log("You didn't hear it from me, but " + what);
    }
};

blogger.addSubscriber(jack.read);
blogger.addSubscriber(jill.gossip);

// 发布者触发函数
blogger.writeBlogPost();
// jack与jill都会收到通知,控制台打印消息

// 任何时候都可以取消订阅
blogger.removeSubscriber(jill.gossip);

la_times.addSubscriber(jill.gossip);
la_times.newIssue();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容

  • 1.什么叫做设计模式(基本概念) 在面向对象软件设计过程中,针对问题进行简洁而优雅的一种解决方案 设计模式是在某种...
    Jianshu9527阅读 336评论 0 3
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,879评论 1 15
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,046评论 1 10
  • 1.发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听...
    JSUED阅读 766评论 1 4
  • 一登上盛世公主号游轮,我就收到一本儿童俱乐部的护照,护照上面有许多的任务,其中有一项任务就是在船上找到不同国...
    萌祺祺kiki阅读 366评论 0 1