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对象返回的对象代码,代码的耦合性较高,我们可以采用工厂方法来对这些代码进行解耦。工厂方法的目的就是为了创建对象。

工厂方法通常在类的静态方法中实现,主要用于创建相似对象时执行重复操作以及为客户端提供创建对象的接口。

下面,我们采用JavaScript实现工厂方法:

  1. 公共父构造函数CacheMaker;
  2. 实现CacheMaker的静态方法factory(),用于创建Cache对象;
  3. 实现CacheMaker.Local, CacheMaker.Session,这些构造函数定义为CacheMaker的静态方法,以便全局命名空间免受污染。

代码如下:

function CacheMaker() {}

CacheMaker.prototype.init = function() {
  console.log('CacheMaker init');
}

CacheMaker.factory = function(type) {
  var constr = type || 'Local';

  //判断构造函数是否存在
  if (typeof CacheMaker[constr] !== 'function') {
    return void 0;
  }

  //使原型继承父类,但仅继承一次
  if (typeof CacheMaker[constr].prototype.init !== 'function') {
    CacheMaker[constr].prototype = new CacheMaker();
  }

  //创建实例
  return new CacheMaker[constr]();
}
//Local构造方法
CacheMaker.Local = function() {
  this.set = function(key, value) {
    console.log('local: ' + key + ' => ' + value);
  };
}
//Session构造方法
CacheMaker.Session = function() {
  this.set = function(key, value) {
    console.log('session: ' + key + ' => ' + value);
  }
}

var local = CacheMaker.factory('Local'),
  session = CacheMaker.factory('Session');

local.set('username', 'wen');  // local: username => wen
session.set('username', 'wen'); // session: username => wen

当需要其他类型的Cache时,只需要增加CacheMaker相对应的静态方法即可。重构后的代码扩展性更好,维护成本也降低了。

设计模式 」相关文章

Wen's Blog

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

订阅

联系方式

链接