zoukankan      html  css  js  c++  java
  • 《Javascript设计模式与开发实践》关于设计模式典型代码的整理:单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式

    1、单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

     使用闭包封装私有变量
    // 使用闭包创建单例
    var user = (function () {
    var _name = 'sven',
    _age = 29;

    return {
    getUserInfo: function () {
    return _name + '-' + _age;
    }
    }
    })();
    惰性单例(只在合适的时候创建对象,并且之创建唯一的一个,试用于dom重复生成、事件绑定等场景)
    // 惰性单例生成
    var getSingle = function (fn) {
    var result;
    return function () {
    return result || (result = fn.apply(this, arguments));
    }
    };
    2、策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

    // 策略模式
    var strategies = {
    "S": function (salary) {
    return salary * 4;
    },
    "A": function (salary) {
    return salary * 3;
    },
    "B": function (salary) {
    return salary * 2;
    },
    };

    var calculateBonus = function (level, salary) {
    return strategies[level](salary);
    }
    // 测试
    console.log(calculateBonus('S', 20000));
    console.log(calculateBonus('A', 10000));
    3、代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。

    // 虚拟代理
    var myImage = (function () {
    var imgNode = document.createElement('img');
    document.body.appendChild(imgNode);

    return {
    setSrc: function (src) {
    imgNode.src = src;
    }
    }
    })();

    var proxyImage = (function () {
    var img = new Image;
    img.onload = function () {
    myImage.setSrc(this.src);
    }
    return {
    setSrc: function (src) {
    myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
    img.src = src;
    }
    }
    })();
    // 测试
    proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
    // 缓存代理
    var mult = function () {
    console.log('开始计算乘积');
    var a = 1;
    for(var i = 0, l = arguments.length; i < l; i++) {
    a = a * arguments[i];
    }
    return a;
    }

    var proxyMult = (function () {
    var cache = {};
    return function () {
    var args = Array.prototype.join.call(arguments, ',');
    if(args in cache) {
    return cache[args];
    }
    return cache[args] = mult.apply(this, arguments);
    }
    })();
    // 测试
    proxyMult(1,2,3,4);
    proxyMult(1,2,3,4);
    4、迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

    // 迭代器模式
    var each = function(ary, callback) {
    for (var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]);
    }
    };
    // 测试
    each([1, 2, 3], function(i, n) {
    alert ([i, n]);
    });
    5、发布-订阅模式:它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。

    // 发布-订阅模式
    var event = {
    clientList: [],
    listen: function (key, fn) {
    if (!this.clientList[key]) {
    this.clientList[key] = [];
    }
    this.clientList[key].push(fn); // 订阅的消息添加进缓存列表
    },
    trigger: function () {
    var key = Array.prototype.shift.call(arguments);
    fns = this.clientList[key];
    if (!fns || fns.length === 0) { // 如果没有绑定对应的消息
    return false;
    }
    for (var i = 0, fn; fn = fns[i++];) {
    fn.apply(this, arguments);
    }
    },
    remove: function (key, fn) {
    var fns = this.clientList[key];
    if (!fns) { // 如果 key 对应的消息没有被人订阅,则直接返回
    return false;
    }
    if (!fn) { // 如果没有传入具体的回调函数,表示需要取消 key 对应消息的所有订阅
    fns && (fns.length = 0);
    } else {
    for (var l = fns.length - 1; l >= 0; l--) {
    var _fn = fns[l];
    if (_fn ===fn) {
    fns.splice(l, 1); // 删除订阅者的回调函数
    }
    }
    }
    }
    };
    // 安装发布—订阅功能
    var installEvent = function (obj) {
    for (var i in event) {
    obj[i] = event[i];
    }
    };
    // 测试
    var salesOffices = {};
    installEvent( salesOffices );

    salesOffices.listen( 'squareMeter88', fn1 = function( price ){
    console.log( '价格= ' + price );
    }); // 小明订阅消息
    salesOffices.listen( 'squareMeter88', fn2 = function( price ){
    console.log( '价格= ' + price );
    }); // 小红订阅消息
    salesOffices.remove( 'squareMeter88', fn1 );
    salesOffices.trigger( 'squareMeter88', 2000000 ); // 输出:2000000
    6、命令模式:用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。

    // 命令模式
    var bindClick = function (button, func) {
    button.onclick = func;
    };

    var MenuBar = {
    refresh: function () {
    console.log('刷新菜单界面');
    }
    };

    var SubMenu = {
    add: function () {
    console.log('增加子菜单');
    },
    del: function () {
    console.log('删除子菜单');
    }
    };
    // 测试
    bindClick(button1, MenuBar.refresh);
    bindClick(button2, SubMenu.add);
    bindClick(button3, SubMenu.del);
    7、组合模式:将对象组合成树形结构,以表示“部分-整体”的层次结构。

    // 组合模式
    var closeDoorCommand = {
    execute: function () {
    console.log('关门');
    }
    };

    var openPcCommand = {
    execute: function () {
    console.log('开电脑');
    }
    };
    var openQQCommand = {
    execute: function () {
    console.log('登录 QQ');
    }
    };

    var MacroCommand = function () {
    return {
    commandsList: [],
    add: function (command) {
    this.commandsList.push(command);
    },
    execute: function () {
    for (var i = 0, command; command = this.commandsList[i++];) {
    command.execute();
    }
    }
    }
    };
    // 测试
    var macroCommand = MacroCommand();
    macroCommand.add(closeDoorCommand);
    macroCommand.add(openPcCommand);
    macroCommand.add(openQQCommand);

    macroCommand.execute(); 

    转自:https://blog.csdn.net/QQsilhonette/article/details/84943932

  • 相关阅读:
    IOS 开发 网络发展史(基础知识)
    加密详解
    IOS对接支付的流程
    App混合开发浅谈
    swift语法100
    2015年最新Android基础入门教程目录第二章:Android UI(User Interface)详解(已完结 40/40)
    2015年最新Android基础入门教程目录第一章:环境搭建与开发相关(已完结 10/10)
    Reactive开发
    tensorflow 安装
    Mask RCNN笔记
  • 原文地址:https://www.cnblogs.com/sweeeper/p/11713807.html
Copyright © 2011-2022 走看看