【第22期】观点:IT 行业加班,到底有没有价值?

javascript设计模式【上】

原创 2017年01月03日 10:25:08

参考《javascript设计模式》[美]Addy Osmani一书,下面介绍使用javascript经常会使用的主要设计模式。本博文是使用ES5语法的【上】篇,还有一个【下】篇,ES6语法会单独写个博客。
主要是以下几个设计模式:

  • Constructor Pattern 构造模式
  • Module Pattern 模块化模式
  • Revealing Module Pattern 揭露模块化模式
  • Singleton Pattern 单例模式
  • Observer Pattern 观察者模式
  • Mediator Pattern 中介者模式
  • Prototype Pattern 原型模式
  • Command Pattern 命令行模式
  • Facade Pattern 外观模式
  • Factory Pattern 工厂模式
  • Mixin Pattern 混入模式
  • Decorator Pattern 装饰者模式
  • Flyweight Pattern 享元模式

所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern

1.Module Pattern 模块化模式

模块化很好理解,目前很多提供模块化的库如require.js(AMD),sea.js(CMD),现在我们就看看怎样自己编写的代码能够支持模块化。

1.1 对象字面量表示法

var myModule = {
    myProperty: "someValue",
    myConfig: {
        useCaching: true,
        language: "en"
    },
    // a very basic method
    myMethod: function() {
        console.log("Where in the world is Paul Irish today?");
    },
};
// Outputs: Where in the world is Paul Irish today?
myModule.myMethod();

1.2 Module(模块)模式

  • 私有–IIFE模拟
var testModule = (function() {
    var counter = 0;
    return {
        incrementCounter: function() {
            return counter++;
        },
        resetCounter: function() {
            console.log("counter value prior to reset: " + counter);
            counter = 0;
        }
    };
})();
// Usage:

testModule.incrementCounter();
testModule.resetCounter(); //1
  • Module(模块)模式变化–混入
var myModule = (function(jQ, _) {
    function privateMethod1() {
        jQ(".container").html("test");
    }
    function privateMethod2() {
        console.log(_.min([10, 5, 100, 2, 1000]));
    }
    return {
        publicMethod: function() {
            privateMethod1();
        }
    };
}(jQuery, _));

myModule.publicMethod();
  • Module(模块)模式变化–引出
var myModule = (function() {
    // Module object
    var module = {},
        privateVariable = "Hello World";
    function privateMethod() {
        // ...
    }
    module.publicProperty = "Foobar";
    module.publicMethod = function() {
        console.log(privateVariable);
    };

    return module;
}());

2.Revealing Module Pattern 揭露模块化模式

其实简单说就是将要暴露的接口返回(return)出去

var myRevealingModule = function() {
    var privateVar = "Ben Cherry",
        publicVar = "Hey there!";

    function privateFunction() {
        console.log("Name:" + privateVar);
    }

    function publicSetName(strName) {
        privateVar = strName;
    }

    function publicGetName() {
        privateFunction();
    }

    return {
        setName: publicSetName,
        greeting: publicVar,
        getName: publicGetName
    };
}();
myRevealingModule.setName("Paul Kinlan");

3.Singleton Pattern 单例模式

确保实例化或者说是创建对象的时候只实例化/创建一次。

var mySingleton = (function() {
    // Instance stores a reference to the Singleton
    var instance;
    function init() {
        // Private methods and variables
        function privateMethod() {
            console.log("I am private");
        }
        var privateVariable = "Im also private";
        var privateRandomNumber = Math.random();
        return {
            // Public methods and variables
            publicMethod: function() {
                console.log("The public can see me!");
            },
            publicProperty: "I am also public",
            getRandomNumber: function() {
                return privateRandomNumber;
            }
        };

    };
    return {
        getInstance: function() {
            if (!instance) {
                instance = init();
            }
            return instance;
        }
    };
})();

// Usage:
var singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); // true
  • 静态方法
    静态方法的解释不太容易说清楚,但可以从它的特点和用处来说明:
    1)静态方法不会被继承
    2)静态方法不用实例化(不用new)能够用直接调用([类名/对象名].[静态方法名])
    ES6在方法前加上static关键字即可,使用ES6实现的见另外一篇博客,或者直接在github中查看我的源代码。使用ES5语法实现见下面:
var SingletonTester = (function() {
    function Singleton(options) {
        options = options || {};
        // set some properties for our singleton
        this.name = "SingletonTester";
        this.pointX = options.pointX || 6;
        this.pointY = options.pointY || 10;
    }
    var instance;
    var _static = {
        name: "SingletonTester",
        getInstance: function(options) {
            if (instance === undefined) {
                instance = new Singleton(options);
            }
            return instance;
        }
    };
    return _static;
})();

var singletonTest = SingletonTester.getInstance({
    pointX: 5
});

console.log(singletonTest.pointX);// Outputs: 5

3.Observer Pattern 观察者模式

观察者一共有四个组件:
* Subject: maintains a list of observers, facilitates adding or removing observers
目标对象(类似接口,不具体实现,只有方法名)
* Observer: provides a update interface for objects that need to be notified of a Subject’s changes of state
观察者对象 主要是update方法(类似接口,不具体实现,只有方法名)
* ConcreteSubject: broadcasts notifications to observers on changes of state, stores the state of ConcreteObservers
具体目标对象,继承(实现)目标对象(实现接口)
* ConcreteObserver: stores a reference to the ConcreteSubject, implements an update interface for the Observer to ensure state is consistent with the Subject’s
具体观察者,继承(实现)观察者(实现接口)

具体观察者模式的代码请移步到我的github中,这里就不单独列出来了。
其实我们现在用的最多的是它的变体-发布-订阅模式
简单解释下该模式,比如我们订阅了某些微信公众号,然后就等着别人发布信息,我们就能立刻接受到信息了。

var pubsub = {};
(function(q) {
    var topics = {},//存放所有订阅者
        subUid = -1;
    //发布
    q.publish = function(topic, args) {

        if (!topics[topic]) {
            return false;
        }

        var subscribers = topics[topic],
            len = subscribers ? subscribers.length : 0;

        while (len--) {
            subscribers[len].func(topic, args);
        }

        return this;
    };
    //订阅
    q.subscribe = function(topic, func) {
        if (!topics[topic]) {
            topics[topic] = [];
        }

        var token = (++subUid).toString();
        topics[topic].push({
            token: token,
            func: func
        });
        return token;
    };
    //取消订阅
    q.unsubscribe = function(token) {
        for (var m in topics) {
            if (topics[m]) {
                for (var i = 0, j = topics[m].length; i < j; i++) {
                    if (topics[m][i].token === token) {
                        topics[m].splice(i, 1);
                        return token;
                    }
                }
            }
        }
        return this;
    };
}(pubsub));
//测试
var messageLogger = function(topics, data) {
    console.log("Logging: " + topics + ": " + data);
};
var subscription = pubsub.subscribe("inbox/newMessage", messageLogger);
pubsub.publish("inbox/newMessage", "hello world!");
// or
pubsub.publish("inbox/newMessage", ["test", "a", "b", "c"]);
// or
pubsub.publish("inbox/newMessage", {
    sender: "hello@google.com",
    body: "Hey again!"
});

4.Mediator Pattern 中介者模式

该模式和发布订阅模式非常像,这里就不再重复了。

5.Command Pattern 命令行模式

命令行模式就是类似控制台输入命令的方式。说白点就是我们只使用一个方法,第一个参数是我们实际调用的方法,后面的参数是作为该调用方法的参数。

(function() {
    var CarManager = {
        requestInfo: function(model, id) {
            return "The information for " + model + " with ID " + id + " is foobar";
        },
        buyVehicle: function(model, id) {
            return "You have successfully purchased Item " + id + ", a " + model;
        },
        arrangeViewing: function(model, id) {
            return "You have successfully booked a viewing of " + model + " ( " + id + ") ";
        }
    };
    CarManager.execute = function(name) {
        return CarManager[name] && CarManager[name].apply(CarManager, [].slice.call(arguments, 1));
    };

    console.log(CarManager.execute("arrangeViewing", "Ferrari", "14523"));
    console.log(CarManager.execute("requestInfo", "Ford Mondeo", "54323"));
    console.log(CarManager.execute("buyVehicle", "Ford Escort", "34232"));
})();

所有代码挂在我的github上,包含有ES5和ES6语法实现的内容。
https://github.com/zrysmt/javascript-design-pattern

版权声明:本文为博主原创文章,转载请注明出处和原文链接。 举报

相关文章推荐

我的JavaScript设计模式

前言JavaScript编设计模式有很多,比较常用的是单例模式、模块模式和观察者模式。这里不一一介绍这些模式的用法和场景。记住,设计模式没有好坏,只有适合不适合。下面简单介绍一下我研究出来的一种Jav...

【JavaScript设计模式】(一)

最近在学习JavaScript设计模式,学习过之后感觉很有收获,现把自己的学习内容总结如下: 模式:是一种可服用的解决方案,可用于解决软件设计中遇到的常见问题。 设计模式:有三大好处,模式是...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

深入理解javascript之设计模式

设计模式 设计模式是命名、抽象和识别对可重用的面向对象设计有用的的通用设计结构。设计模式确定类和他们的实体、他们的角色和协作、还有他们的责任分配。 每一个设计模式都聚焦于一个面向对象的设计难题或问...

javascript模式--模块模式

javascript模式 Module(模块)模式

JavaScript设计模式--模板方法模式

一、定义模板方法是基于继承的设计模式,可以很好的提高系统的扩展性。 java中的抽象父类、子类 模板方法有两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。二、示例Coffee or T...

javascript常见编程模式举例

最近买到手了一本《javascript框架设计》,详细介绍开发js框架所用到的知识。初读一点,乐帝脆弱的理论修养就暴露无遗了,所以专门加强理论修养,重看javascript编程模式的举例。下面来介绍下...

JavaScript设计模式--观察者模式

一、定义观察者模式(发布-订阅模式):其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 在JavaScript中,一般使用事件模型来替代传统的观察者模式...

JavaScript设计模式 --- 单体模式

单体模式单体模式是javascript中最基本但最有用的模式之一。 这种模式提供了一种将代码组织为一个逻辑单元的手段,这个逻辑单元中的代码可以通过单一的变量进行访问。通过确保单体对象只存在一个实例。...

JavaScript设计模式----装饰者模式

装饰者模式的定义:装饰者(decorator)模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责。与继承相比,装饰者是一种更轻便灵活的做法。装饰者模式的特点:可以动态的给某个对象添加...

深入理解JavaScript系列(42):设计模式之原型模式

深入理解JavaScript系列(42):设计模式之原型模式 2012-04-16 09:11 by 汤姆大叔, 3146 阅读, 5 评论, 收藏, 编辑 介绍 原型模式(proto...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)