几种常见的js设计模式

更新日期: 2019-05-25阅读: 3.5k标签: 模式

单例模式

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

这里其实利用的是 js闭包 来实现这样的功能。

假如现在我们有这样的需求,设置一个管理员,无论创建多次都只是设置一次。


function SetManager(name) {
  this.manager = name;
}

SetManager.prototype.getName = function() {
  console.log(this.manager);
};

var SingletonSetManager = (function() {
  var manager = null;

  return function(name) {
    if (!manager) {
        manager = new SetManager(name);
    }

    return manager;
  }
})();

SingletonSetManager('a').getName(); // a
SingletonSetManager('b').getName(); // a
SingletonSetManager('c').getName(); // a

这种方法有一个缺点就是:如果我们需要再次创建一个 HR,则需要将代码再复制一遍,所以我们可以提取通用的单例。

function getSingleton(fn) {
  var instance = null;

  return function() {
    if (!instance) {
        instance = fn.apply(this, arguments);
    }

    return instance;
  }
}


// 设置管理员
var managerSingleton = getSingleton(function(name){
  var manager = new SetManager(name);
  return manager;
})

managerSingleton('a').getName(); // a
managerSingleton('b').getName(); // a
managerSingleton('c').getName(); // a

// 设置 HR

function SetHr(name) {
  this.hr = name;
}

SetHr.prototype.getName = function() {
  console.log(this.hr);
};

var hrSingleton = getSingleton(function(name) {
  var hr = new SetHr(name);
  return hr;
});

hrSingleton('aa').getName(); // aa
hrSingleton('bb').getName(); // aa
hrSingleton('cc').getName(); // aa

这样我们的代码可通用性就会变得更好,省去了一些重复性的代码。


代理模式

所谓代理模式就是:我们不方便直接访问某个对象时,可以为对象创建一个占位符(代理),以便控制对它的访问,我们实际上访问的是代理对象。

这里我们以一个过滤敏感字符来说明这种模式

// 主体,发送消息
function sendMsg(msg) {
  console.log(msg);
}

// 代理,对消息进行过滤
function proxySendMsg(msg) {
  // 无消息则直接返回
  if (typeof msg === 'undefined') {
    console.log(null);
    return;
  }
  
  // 有消息则进行过滤
  msg = ('' + msg).replace(/泥\s*煤/g, '');

  sendMsg(msg);
}


sendMsg('泥煤呀泥 煤呀'); // 泥煤呀泥 煤呀
proxySendMsg('泥煤呀泥 煤'); // 呀
proxySendMsg(); // null

这样操作的意图很明显,当没有消息的时候,控制对主体对象的访问,代理直接返回一个 null ,有消息,则会过滤掉敏感字符,实现虚拟代理。


策略模式

策略模式就是内部封装一些算法,它们之间可以互相替换,但是它们不随客户端变化而变化。

策略模式我们外部看不到算法的具体实现,我们也只关心算法实现的结果,不关注过程。

这里以一个商品促销的例子来说明下:在圣诞节,某些商品需要八折出售,有些商品需要九折出售,到了元旦节,普通客户满100减30,vip客户满100减50。可以看到商品出售的价格需要根据不同的条件来规定,分别采取不同的算法实现,所以我们采用策略模式。

// 价格策略对象
class PriceStrategy {
  constructor() {
      // 内部算法对象
    this.stragtegy = {
        // 100返30
      return30(price) {
          return +price + parseInt( price / 100) * 30;
      },
      // 100 返 50
      return50(price) {
          return +price + parseInt(price/ 100) * 50;
      },
      // 9 折
      percent90(price) {
          return price * 100 * 90 / 10000
      },
      percent80(price) {
          return price * 100 * 80 / 10000
      },
      percent50(price) {
          return price * 100 * 50 / 10000
      }
    }
  }
  // 策略算法调用接口
  getPrice(algorithm, price) {
    return this.stragtegy[algorithm] && this.stragtegy[algorithm](price);
  }
}
let priceStrategy = new PriceStrategy();
let price = priceStrategy.getPrice('return50', 314.67);
console.log(price);

这样,我们可以采取不同的策略算法得到商品的不同价格。


观察者模式

观察者模式又称为 “发布-订阅模式”,通过定义一种依赖关系,当一个对象状态发生改变时,订阅者会得到通知。

其实,我们传统的 dom 事件绑定就是一种发布-订阅模式。

// 订阅
document.body.addEventListener('click', function() {
  console.log('click1');
}, false);

document.body.addEventListener('click', function() {
  console.log('click2');
}, false);

// 发布
document.body.click(); // click1  click2


装饰者模式

装饰者模式就是在不改变原对象基本功能的基础上,通过增加功能使得原本对象满足用户的更为复杂的需求。

比如有这么一个需求:

用户点击输入框时,如果输入框输入的内容有限制,那么在其后面显示用户输入内容的限制格式的提示文案

---------------->>>>>>> 现在要改为:

多加一条需求,默认输入框上边显示一行文案,当用户点击输入框的时候,文案消失。

这里是以前的代码:

// 输入框元素
let telInput = document.getElementById('tel_input');
// 输入框提示文案
let telWarnText = document.getElementById('tel_warn_text');
// 点击输入框显示输入框输入格式提示文案
input.onclick = function () {
  telWarnText.style.display = 'inline-block';
};

修改之后的代码:

// 输入框元素
let telInput = document.getElementById('tel_input');
// 输入框输入格式提示文案
let telWarnText = document.getElementById('tel_warn_text');
// 输入框提示输入文案
let telDemoText = document.getElementById('tel_demo_text');
// 点击输入框显示输入框输入格式提示文案
input.onclick = function () {
  telWarnText.style.display = 'inline-block';
  telDemoText.style.display = 'none';
};

但是紧接着悲剧就来了,修改了电话输入框,还有姓名、地址输入框等等;

装饰已有的功能对象

原有的功能已经不满足用户的需求了,此时需要做的是对原有的功能添加,设置新的属性和方法来满足新的需求,但是有不影响原来已经有的部分。

let decorator = function (input, fn) {
  let getInput = document.getElementById(input);
  if(typeof getInput.onclick === 'function') {
    let oldClick = getInput.onclick;
    getInput.onclick = function() {
        // 原来的事件回调函数
        oldClick();
        // 新增的事件回调函数
        fn();
    }
  } else {
    getInput.onclick = fn;
  }
  // 其他事件
};

// 电话输入框功能装饰
decorator('tel_input', function() {
  document.getElementById('tel_demo_text').sytle.display = 'none'
});
// 姓名输入框装饰
decorator('name_input', function() {
  document.getElementById('name_demo_text').sytle.display = 'none'
});
// 地址输入框装饰
decorator('address_input', function() {
  document.getElementById('address_demo_text').sytle.display = 'none'
});

来自:https://www.cnblogs.com/dreamcc/archive/2019/06/25/11083818.html


链接: https://www.fly63.com/article/detial/3891

js设计模式之单例模式,javascript如何将一个对象设计成单例

单例模式是我们开发中一个非常典型的设计模式,js单例模式要保证全局只生成唯一实例,提供一个单一的访问入口,单例的对象不同于静态类,我们可以延迟单例对象的初始化,通常这种情况发生在我们需要等待加载创建单例的依赖。

前端设计模式:从js原始模式开始,去理解Js工厂模式和构造函数模式

工厂模式下的对象我们不能识别它的类型,由于typeof返回的都是object类型,不知道它是那个对象的实例。另外每次造人时都要创建一个独立的person的对象,会造成代码臃肿的情况。

JavaScript设计模式_js实现建造者模式

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象

html和xhtml,DOCTYPE和DTD,标准模式和兼容模式

主要涉及知识点: HTML与XHTML,HTML与XHTML的区别,DOCTYPE与DTD的概念,DTD的分类以及DOCTYPE的声明方式,标准模式(Standard Mode)和兼容模式(Quircks Mode),标准模式(Standard Mode)和兼容模式(Quircks Mode)的区别

前端四种设计模式_JS常见的4种模式

JavaScript中常见的四种设计模式:工厂模式、单例模式、沙箱模式、发布者订阅模式

javascript 策略模式_理解js中的策略模式

javascript 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句,策略模式提供了开放-封闭原则,使代码更容易理解和扩展, 策略模式中的代码可以复用。

javascript观察者模式_深入理解js中的观察者模式

javascript观察者模式又叫发布订阅模式,观察者模式的好处:js观察者模式支持简单的广播通信,自动通知所有已经订阅过的对象。存在一种动态关联,增加了灵活性。目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。

Vue中如何使用方法、计算属性或观察者

熟悉 Vue 的都知道 方法methods、计算属性computed、观察者watcher 在 Vue 中有着非常重要的作用,有些时候我们实现一个功能的时候可以使用它们中任何一个都是可以的

我最喜欢的 JavaScript 设计模式

我觉得聊一下我爱用的 JavaScript 设计模式应该很有意思。我是一步一步才定下来的,经过一段时间从各种来源吸收和适应直到达到一个能提供我所需的灵活性的模式。让我给你看看概览,然后再来看它是怎么形成的

Flutter 设计模式 - 简单工厂

在围绕设计模式的话题中,工厂这个词频繁出现,从 简单工厂 模式到 工厂方法 模式,再到 抽象工厂 模式。工厂名称含义是制造产品的工业场所,应用在面向对象中,顺理成章地成为了比较典型的创建型模式

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!