设计模式

设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。

设计模式主要分为3类:

创建型设计模式:专注于处理对象的创建

Constructor构造器模式,Factory工厂模式,Singleton单例模式,builder生成器模式

结构型设计模式:对象间组合,建立对象之间的关系

Decorator装饰者模式,Facade外观模式,Flyweight享元模式,Adapter适配器模式,Proxy代理模式

行为设计模式:简化和改善对象间的通信

Mediator中介者模式,Observer观察者模式

常用的设计模式

1. 观察者模式

一个目标对象维持着一系列依赖于它的对象,将有关状态的任何变更自动通知观察者们。在观察者模式中,观察者需要直接订阅目标对象,观察者与目标对象之间有一定的依赖关系。 有4个重要的概念

  • 目标对象(被观察者):维护一组观察患者,提供管理观察者的方法。
  • 观察者: 提供一个更新接口,用于收到通知时,进行更新
  • 具体目标对象:代表具体的目标对象
  • 具体观察者:代表具体的观察者
// 目标对象
class Subject {constructor() {// 观察者列表this.observers = []}addObserver(observer) {this.observers.push(observer)}removeObserver() {this.observers.pop()}notify() {this.observers.forEach(observer => {observer.update()})}
}// 观察者
class Observer {constructor() {// 使用时会被具体update方法覆盖this.update = function () {// ..}}
}
// 具体目标对象
class currentSubject extends Subject {constructor() {super()    }// 其他自定义方法dosomething() {console.log('currentSubject change')this.notify()}
}
// 具体观察者
class currentObserver extends Observer {constructor() {super()}// 重写updateupdate() {console.log('change!')}
}
// 订阅
let curSubject = new currentSubject()
let curObserver = new currentObserver()
curSubject.addObserver(curObserver)
// 触发
curSubject.dosomething()
// currentSubject change

2.发布/订阅模式

发布订阅模式可以说是观察这模式的一种变体,一种实现。它使用一个主题/事件通道,介于发布者和订阅者之间,避免了发布者和订阅者之间的依赖关系。

class PubSub {constructor() {
// 主题/事件通道this.topics = {}}publish(topic, args) {if (!this.topics[topic]) {return}let subscribers = this.topics[topic]subscribers.forEach(subscriber => {subscriber.updata(args)})}subscribe(topic, subscriber ) {if (!this.topics[topic]) {this.topics[topic] = []}this.topics[topic].push(subscriber )}
}let pubsub = new PubSub()pubsub.subscribe('one', subscriber )pubsub.publish('one', 'some args')

3. 工厂模式

工厂函数提供一个通用的接口来创建对象,我们可以指定我们希望创建的对象类型,我们通知工厂函数需要什么类型的对象并提供对应的数据,返回对应的实例。

class Car {constructor(options) {this.doors = options.doors || 4;this.state = options.state || "brand new";this.color = options.color || "silver";}
}class Truck {constructor(options) {this.state = options.state || "used";this.wheelSize = options.wheelSize || "large";this.color = options.color || "blue";}
}function vehicleFactory (options) {if (options.type === 'car') {return new Car(options)  } else {return new Truck(options)}
}

何时使用工厂模式

  • 当我们的对象比较复杂的时候。
  • 当我们需要根据不同情况创建不同对象实例的时候。
  • 当我们需要创建许多相似对象的时候。

缺点

  • 使用不当会增加程序的复杂度

4. 抽象工厂模式

抽象工厂模式,将对象的实现细节抽离出来。适用于需要和多种对象一起工作的场景。

class Truck {constructor(options) {this.state = options.state || "used";this.wheelSize = options.wheelSize || "large";this.color = options.color || "blue";}
}class Car {constructor(options) {this.doors = options.doors || 4;this.state = options.state || "brand new";this.color = options.color || "silver";}
}class AbstractFactory {constructor() {this.types = {}}registerFactory(type, factory) {this.types[type] = factory}getInstance(type, args) {let factory = this.types[type]if (factory) {return new factory(args)}}
}let abstractFactory = new AbortController()
abstractFactory.registerFactory('car', Car)
abstractFactory.registerFactory('truck', Truck)abstractFactory.getInstance('car', options)
abstractFactory.getInstance('truck', options)

5. 单例模式

单例模式限制一个类只有一个实例化对象。

class Obj(data) {// ....
}
// 利用闭包实现单例模式,确保obj类只有一个实例
function singleton (data) {var instance;return function () {if (!instance) {instance = new Obj(data)}return instance}
}

6. 中介者模式

中介者模式就是提供一个中心点给系统不同组件之间进行通信,降低系统组件之间的耦合程度。

// 实现与发布/订阅模式类似

观察者模式和发布订阅模式专注于维护目标对象和观察者之间的关系,当主题对象发送变化时,通知所有对改主题感兴趣的观察者。而中介者模式的话,专注于限制对象的通信必须通过中介者来通信。两者都提倡松耦合。

7. 装饰者模式

装饰者模式,通过一个装饰类对现有动态添加行为,以及对原有行为进行装饰。

  // o为已有对象var M20 = function(o){    // 这里定义一个装饰类var str = '20多岁的时候,';// o是传入的对象,调用传入对象的方法,加以装饰this.eat = function(){return str + o.eat()+",肥得很!";};this.drink = function(){return str + o.drink()+",就是个水桶!";};this.coding = function(){return str + o.coding()+",代码又写得撇!";};}alert(new M20(david).eat());    // 20多岁的时候,大卫是个大胖子,一天只晓得吃,肥得很!alert(new M20(david).drink());    // 20多岁的时候,大卫除了吃就是喝,就是个水桶!alert(new M20(david).coding());    // 20多岁的时候,写代码吧,大卫,代码又写得撇!

8. 适配器模式

使用一个新的接口对现有的接口进行包装,处理数据与接口的不匹配。

function api (x1, x2, x3) {console.log(x1 + x2 + x3);  // 用console.log来模拟接口的相关操作
}var data = {a: '我',b: '很',c: '帅'
}function adapterApi (o) {// 通过适配器函数来调用目的apiapi(o.a, o.b, o.c);
} adapterApi(data);
// 我很帅

原文发布时间为:2018年07月02日
原文作者:掘金
本文来源:掘金 如需转载请联系原作者

JavaScript常用设计模式相关推荐

  1. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  2. Javascript常用的设计模式详解

    Javascript常用的设计模式详解 阅读目录 一:理解工厂模式 二:理解单体模式 三:理解模块模式 四:理解代理模式 五:理解职责链模式 六:命令模式的理解: 七:模板方法模式 八:理解javas ...

  3. JavaScript 经典设计模式

    文章出自个人博客https://knightyun.github.io/2021/01/17/js-design-pattern,转载请申明 设计模式(Design Pattern)是一套被反复使用的 ...

  4. JavaScript常见设计模式

    Javascript常⻅设计模式 设计模式总的来说是一个抽象的概念,是软件开发人员在开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过相当⻓的一段时间的试验和错误总结出来的. 1 ...

  5. JavaScript常用代码

    在这存一下JavaScript常用代码: 1.封装输出 1 var log = function() { 2 console.log.apply(console, arguments) 3 } 4 5 ...

  6. javaScript常用知识点有哪些

    javaScript常用知识点有哪些 一.总结 一句话总结:int = ~~myVar, // to integer | 是二进制或, x|0 永远等于x:^为异或,同0异1,所以 x^0 还是永远等 ...

  7. javascript常用代码大全

    http://caibaojian.com/288.html     原文链接 jquery选中radio//如果之前有选中的,则把选中radio取消掉 $("#tj_cat .pro_ca ...

  8. javascript常用的事件

    javascript常用的事件 目标:本章主要讲解一些日常学习中常用的事件种类,主要分为五种事件,分别为鼠标事件.键盘事件.表单事件,页面事件,监听器 1.鼠标事件 1.onclick 鼠标点击触发事 ...

  9. 107条javascript常用小技巧

    107条javascript常用的方法技巧,呵呵!为什么就是108呢? 1.document.write(""); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是: ...

最新文章

  1. 读书:历史 -- 海上丝绸之路
  2. EditText的另类用法
  3. ajax不能设置哪些header
  4. 获得主机域名及其IP和Port端口
  5. 从分子层面雕刻肌肉,新数学模型预测锻炼肌肉最优方式
  6. selenium java测试_java+selenium 自动化测试
  7. 搜索 由浅入深 之一 水题
  8. python开发之路---第二章之--函数之匿名函数
  9. C# Wpf异步修改UI,多线程修改UI(二)
  10. 小程序登录本地服务器,微信小程序实现用户登录模块服务器搭建
  11. 帝国cms数据库php调用tag,帝国CMS列表内容模板调用TAG的两种方法
  12. RADIO控件变量添加
  13. 什么?print 函数还可以打印彩色围棋局面?
  14. 19生成材料清单_爷青没!SU不止能建模,物料清单也能做
  15. COLING 2020 | 一种从科学文献中提取关键词的基于自蒸馏的联合学习方法
  16. 打造真正理想中的会呼吸的智慧城市
  17. Python 面试宝典
  18. 2020年大数据就业前景
  19. c++某商店开展买一送一活动,购买两件商品时,只需支付价格较高的商品的金额。要求程序在输入两个商品的价格后,输出所应支付的金额,请根据裁判程序编写函数cut,将代码补充完整。
  20. 最新易语言安卓逆向视频教程

热门文章

  1. spring核心:bean工厂的装配 2
  2. .net的辅助工具列表
  3. ADO.NET Entity Framework 学习(1)
  4. 微信小程序入门 ——增删改查+页面跳转+传值取值+布局样式
  5. 详解 Blockchain Cuties (区块链萌宠)
  6. Unity3D GUI笔记
  7. 问题六十八:BRDF——(着色模型(shading model)(1)——反射模型(reflection model)(3.2))
  8. vim python3开发环境_[宜配屋]听图阁 - ubuntu16.04制作vim和python3的开发环境
  9. 34(数组). 在排序数组中查找元素的第一个和最后一个位置
  10. Characterizing stochastic time series with ordinal networks