前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「持续更新中」JavaScript 设计模式精简代码实现

「持续更新中」JavaScript 设计模式精简代码实现

作者头像
逆葵
发布2019-04-25 11:10:17
4410
发布2019-04-25 11:10:17
举报
文章被收录于专栏:FECoding

1. Module(模块)模式

代码语言:javascript
复制
var testModule = (function(){
  var counter = 0;
  return {
    incrementCounter: function() {
      return ++counter;
    },
    resetCounter: function() {
      conter = 0;
    }
  };
})();

// 增加计数器
testModule.incrementCounter();

2. Revealing Module(揭示模块)模式

代码语言:javascript
复制
var myRevealingModule = (function (){
  var privateCounter = 0;
  function privateFunction () {
    privateCounter++;
  }

  function publicIncrement () {
    privateFunction();
  }

  function publicFunction () {
    publicIncrement();
  }

  function publicGetCount () {
    return privateCounter;
  }

  myRevealingModule.start();

  // 将暴露的共有指针指向到私有函数和属性上
  return {
    start: publicFunction,
    increment: publicIncrement,
    count: publicGetCount
  }
})();

3. Singleton(单例)模式

代码语言:javascript
复制
var mySingleton = (function () {
  // 实例保持了 Singleton 的一个引用
  var instance;
  function init() {
    // Singleton 私有方法和变量
    function privateMethod () {
      console.log('i am private');
    }
    var privateRandomNumber = Math.random();
    return {
      // 公有方法和变量
      publicMethod: function () {
        console.log('The public can see me!');
      },
      getRandomNumber: function () {
        return privateRandomNumber;
      }
    };
  }

  return {
    // 获取 Singleton 的实例,如果存在就返回,不存在就创建新实例
    getInstance: function () {
      if (!instance) {
        instance = init();
      } else {
        return instance;
      }
    }
  };
})();

4. Observer(观察者)模式

代码语言:javascript
复制
// 一个目标可能拥有的一系列 Observer
function ObserverList () {
  this.observerList = [];
}

ObserverList.prototype.Add = function(obj) {
  return this.observerList.push(obj);
}
ObserverList.prototype.Empty = function() {
  this.observerList = [];
}
ObserverList.prototype.Count = function() {
  return this.observerList.length;
}
ObserverList.prototype.Get = function(index) {
  if (index > -1 && index < this.observerList.length) {
    return this.observerList[index];    
  }
}
ObserverList.prototype.Insert = function (obj, index) {
  // ...
}
ObserverList.prototype.IndexOf = function (obj, startIndex) {
  // ...
}
ObserverList.prototype.RemoveIndexAt = function (index) {
  // ...
}

// 模拟目标,以及在其上添加、删除或通知观察者
function Subject () {
  this.observers = new ObserverList();
}

Subject.prototype.AddObserver = function (observer) {
  this.observers.Add(observer);
}

Subject.prototype.RemoveObserver = function (observer) {
  this.observers.RemoveIndexAt(this.observers.IndexOf(observer));
}

Subject.prototype.Notify = function (context) {
  var observerCount = this.observers.Count();
  for (var i = 0; i < observerCount; i++) {
    // 观察者模式的最核心之处
    // 要求每个观察者必须要有固定的函数用来接收更新,这里就是 Update 函数
    this.observers.Get(i).Update(context);
  }
}

function Observer () {
  this.Update = function () {
    // ...
  }
}

4.1 Publish/Subscribe(发布/订阅)模式

代码语言:javascript
复制
// 相比观察者模式,发布/订阅模式使用了一个 Event Channel,用于解耦观察者与目标

var pubsub = {};
(function(q){
  var topics = {},
      subUid = -1;
  
  // 发布或广播事件,包含特定的 topic 名称和参数(比如传递的数据)
  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;
  };

  // 通过特定的名称和回调函数订阅事件,topic/event 触发时执行事件
  q.subscribe = function (topic, func) {
    if (!topics[topic]) {
      topics[topic] = [];
    }
    var token = (++subUid).toString();
    topics[topic].push({
      token: token,
      func: func
    });
    return token;
  };

  // 基于订阅上的标记引用,通过特定 topic 取消订阅
  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);

5. Mediator(中介者)模式

代码语言:javascript
复制
var mediator = (function(){
  // 存储可被广播或监听的 event
  var events = {};

  // 订阅一个 event,提供一个回调函数,一旦 event 被广播就执行该回调
  var subscribe = function (event, fn) {
    if (!events[event]) {
      events[event] = [];
    }
    events[event].push({
      context: this,
      callback: fn
    });
    return this;
  }

  var publish = function (event) {
    var args;
    if (!events[event]) {
      return false;
    }
    args = Array.prototype.slice.call(arguments, 1);
    for (var i = 0, l = events[event].length; i < l; i++) {
      var subscription = events[event][i];
      subscription.callback.apply(subscription.context, args);
    }
    return this;
  };

  return {
    Publish: publish,
    Subscribe: subscribe,
    installTo: function (obj) {
      obj.subscribe = subscribe
      obj.publish = publish;
    }
  }
})();

6. Prototype(原型)模式

代码语言:javascript
复制
var vehiclePrototype = {
  init: function (carModel) {
    this.model = carModel;
  },
  getModel: function () {
    console.log('The model of this vehicle is..' + this.model);
  }
};

function vehicle (model) {
  function F () {}
  F.prototype = vehiclePrototype;

  var f = new F();
  f.init(model);
  return f;
}

var car = vehicle('Ford Escort');
car.getModel();

7. Command(命令)模式

代码语言:javascript
复制
// old
var CarManager = {
  requestInfo: function () {},
  buyVehicle: function () {},
  arrangeViewing: function () {}
}
// new 
CarManager.execute = function (name) {
  return CarManager[name] && CarManager[name].apply(CarManager, [].slice.call(arguments, 1));
}
// use
CarManager.execute('buyVehicle', 'Ford Escort', '454545');

8. Facade(外观)模式

代码语言:javascript
复制
// 提供高层次的接口,抹平和隐藏底层的复杂性
var addMyEvent = function(el, ev, fn) {
    if (el.addEventListener) {
        el.addEventListener(ev, fn, false);
    } else if (el.attachEvent) {
        el.attachEvent('on' + ev, fn, false);
    } else {
        el['on' + ev] = fn;
    }
}

9. Factory(工厂)模式

代码语言:javascript
复制
// 定义 Car 构造函数
function Car(options) {
    this.doors = options.doors || 4;
    this.state = options.state || 'brand new';
    this.color = options.color || 'silver';
}

// 定义 Truck 构造函数
function Truck(options) {
    this.state = options.state || 'used';
    this.wheelSize = options.wheelSize || 'large';
    this.color = options.color || 'blue';
}

// vehicle 工厂函数
function VehicleFactory() {}
VehicleFactory.prototype.vehicleClass = Car;
// 创建新 vehicle 实例的工厂方法
VehicleFactory.prototype.createVehicle = function(options) {
    if (options.vehicleType === 'car') {
        this.vehicleClass = Car;
    } else {
        this.vehicleClass = Truck;
    }
    return new this.vehicleClass(options);
}

9.1 Abstract Factory(抽象工厂)模式

代码语言:javascript
复制
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Module(模块)模式
  • 2. Revealing Module(揭示模块)模式
  • 3. Singleton(单例)模式
  • 4. Observer(观察者)模式
    • 4.1 Publish/Subscribe(发布/订阅)模式
    • 5. Mediator(中介者)模式
    • 6. Prototype(原型)模式
    • 7. Command(命令)模式
    • 8. Facade(外观)模式
    • 9. Factory(工厂)模式
      • 9.1 Abstract Factory(抽象工厂)模式
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档