资讯专栏INFORMATION COLUMN

JavaScript常用设计模式

RyanHoo / 785人阅读

摘要:原文链接常用设计模式设计模式设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。用来模拟接口的相关操作我很帅通过适配器函数来调用目的我很帅学习资料听飞狐聊设计模式系列设计模式汤姆大叔

原文链接: JavaScript常用设计模式
设计模式

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

设计模式主要分为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()
    }
    // 重写update
    update() {
        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) {
  // 通过适配器函数来调用目的api
  api(o.a, o.b, o.c);
} 

adapterApi(data);
// 我很帅

学习资料:
听飞狐聊JavaScript设计模式系列
javascript设计模式
汤姆大叔

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95824.html

相关文章

  • +【13】JavaScript设计原则&&常用设计模式

    摘要:打个比方源码使用了模式,解决了问题,但是,在选择模式解决问题的背后又有多少思考 showImg(https://segmentfault.com/img/bVbupTE?w=480&h=260); 【前言】 最近阅读了《JavaScript设计模式与开发实践》,收获颇丰,于是想写一点总结及感想 showImg(https://segmentfault.com/img/bVbupUE?w...

    opengps 评论0 收藏0
  • JavaScript常用设计模式

    摘要:前言设计模式几十种,阅读了设计模式与开发实践这本书后,个人感觉就是围绕对象来设计的,发现日常写代码能用上的并不多,下面是常用的几种设计模式。前端服务端可以参考我的另一个仓库地址,一个简单的实时聊天参考来自设计模式与开发实践读书笔记 前言 设计模式几十种,阅读了《JavaScript设计模式与开发实践》这本书后,个人感觉js就是围绕对象来设计的,发现日常写代码能用上的并不多,下面是常用的...

    mengbo 评论0 收藏0
  • 学Java编程需要注意的地方

    摘要:学编程真的不是一件容易的事不管你多喜欢或是多会编程,在学习和解决问题上总会碰到障碍。熟练掌握核心内容,特别是和多线程初步具备面向对象设计和编程的能力掌握基本的优化策略。   学Java编程真的不是一件容易的事,不管你多喜欢或是多会Java编程,在学习和解决问题上总会碰到障碍。工作的时间越久就越能明白这个道理。不过这倒是一个让人进步的机会,因为你要一直不断的学习才能很好的解决你面前的难题...

    leanxi 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • 个人分享--web前端学习资源分享

    摘要:前言月份开始出没社区,现在差不多月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了一般来说,差不多到了转正的时候,会进行总结或者分享会议那么今天我就把看过的一些学习资源主要是博客,博文推荐分享给大家。 1.前言 6月份开始出没社区,现在差不多9月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了!一般来说,差不多到了转正的时候,会进行总结或者分享会议!那么今天我就...

    sherlock221 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<