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();

你可能感兴趣的:(JS设计模式)