JavaScript设计模式之外观模式

July 5, 2015

596

外观(Facade)模式为对象提供了一个方便的高层次接口,能够隐藏其底层的真实复杂性,通常是为了提高可用性。

外观模式非常适合于浏览器脚本处理,可以将浏览器之间的差异隐藏在外观之后。比如说事件API、AJAX等,IE低版本浏览器和W3C标准存在一定差异,这时候可以提供一个“外观”给外部调用,将处理细节隐藏起来,同时也能将细节处理的代码从逻辑代码中解耦出来。

以下内容通过提供一个跨浏览器事件的接口来实现外观模式。

通过创建一个工具类utils,主要包含addEventListener和removeEventListener,通过检查特性的存在来提供一个更安全的、跨浏览器的API。代码如下:

var utils = {
  addEventListener: function (el, ev, handler) {
    if (el.addEventListener) {
      el.addEventListener(ev, handler, false);
    } else if (el.attachEvent) {
      el.attachEvent('on' + ev, handler);
    } else {
      el['on' + ev] = handler;
    }
  },
  removeEventListener: function (el, ev, handler) {
    if (el.addEventListener) {
      el.removeEventListener(ev, handler, false);
    } else if (el.attachEvent) {
      el.detachEvent('on' + ev, handler);
    } else {
      el['on' + ev] = null;
    }
  }
};

这就是一个外观模式。但这段代码存在一个问题,执行效率比较低下。每次在调用utils.addEventListener()或utils.removeEventListener()时,都会重复执行相同的检查。那么该如何优化这段代码?

JavaScript设计模式之单例模式

June 15, 2015

801

Singleton(单例)模式限制了类的实例化次数只能一次,以前使用PHP的时候,常用单例模式来处理数据库连接,保证数据库句柄唯一。

Singleton模式,在实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,它会简单返回该对象的引用。

今天,采用JavaScript来实现单例模式。在JavaScript中,有多种方式可以实现单例模式。

1、使用对象字面值

代码如下:

var obj = {
  name: 'wen'
};

在JavaScript中,对象之间永远不会完全相等,因此,可以认为在使用对象字面量创建对象的时候,就是创建一个单例。

2、重写构造函数

代码如下:

function Singleton() {
  //缓存实例
  var instance;

  //重写构造函数
  Singleton = function() {
    return instance;
  };

  //保留原型
  Singleton.prototype = this;

  //实例
  instance = new Singleton();

  //构造函数指针
  instance.constructor = Singleton;

  return instance;
}

JavaScript设计模式之观察者模式

Apr 12, 2015

776

观察者模式是一种设计模式,其中一个对象(Subject)维持一系列依赖于它(Observer)的对象,将有关状态的任何变更自动通知给它们。当一个目标需要告诉观察者发生了什么事情,它会向观察者广播一个通知。以下我们采用JavaScript来实现观察者模式。

  • Subject(目标):维护一系列的观察者,方便添加或删除观察者。
  • Observer(观察者):为那些在目标状态发生改变时需获得通知的对象提供一个更新接口。

首先,实现一个ObserList,用于存储一系列的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.IndexOf = function(obj, startIndex) {
  var i = startIndex, pointer = -1;

  while (i < this.observerList.length) {
    if (this.observerList[i] === obj) {
      pointer = i;
      break;
    }
    i++;
  }

  return pointer;
};

ObserverList.prototype.RemoveIndexAt = function(index) {
  if (index > -1 && index < this.observerList.length) {
    this.observerList.splice(index, 1);
  }
};

接着,实现Observer,代码如下:

function Observer() {
  this.id = Math.floor(Math.random() * 100);
}

Observer.prototype.Update = function(value) {
  console.log(value + this.id);
};

JavaScript设计模式之工厂方法

Mar 8, 2015

316

我们来看一个例子,使用Cache('local').set('username', 'wen')设置一个localStorage键为username,值为wen的本地缓存。

先来分析Cache('local').set('username', 'wen')这段代码,Cache('local')返回一个对象,然后调用对象的set方法。

我第一反应是采用一个闭包来生成对象,示例代码如下:

var Cache = (function(){
  var local = {
    set: function(key, value) {
      console.log('local: ' + key + ' => ' + value);
    }
  },
  session = {
    set: function(key, value) {
      console.log('session: ' + key + ' => ' + value);
    }
  };

  return function(type) {
    type = type || 'local';
    switch (type){
      case 'local' :
        return local;
      case 'session' : 
        return session;
      default: 
        return void 0;
    }
  };
}());
Cache('local').set('username', 'wen'); //local: 
Cache().set('username', 'wen'); //local: username => wen
Cache('session').set('username', 'wen'); //session: username => wen

在这个例子中,每次增加一个对象,还必须修改Cache对象返回的对象代码,代码的耦合性较高,我们可以采用工厂方法来对这些代码进行解耦。工厂方法的目的就是为了创建对象。

Wen's Blog

文章归档 » 文章标签 » 博主:吴文伟,Web开发爱好者,专注于前端开发,该博客用于记录和分享平时遇到的一些问题以及知识。

订阅

联系方式

链接