《javascript设计模式》笔记之第七章:工厂模式

在读了这章之后,根据我个人现在的理解,工厂模式就是:将一个类或者一个方法称为一个工厂,然后再将一些模块交给这个工厂,让这个工厂按照给它的不同模块产出不同的实例。

下面为正文:
一:简单工厂
例子:
分两部分,第一部分:单车厂(负责产出单车)
var BicycleFactory = {
  createBicycle: function(model) {
    var bicycle;
    
    switch(model) {
      case 'The Speedster':
        bicycle = new Speedster();
        break;
      case 'The Lowrider':
        bicycle = new Lowrider();
        break;
      case 'The Flatlander':
        bicycle = new Flatlander();
        break;
      case 'The Comfort Cruiser':
      default:
        bicycle = new ComfortCruiser();
    }
    
    Interface.ensureImplements(bicycle, Bicycle);
    return bicycle;
  }
};
第二部分:单车店,负责买单车
var BicycleShop = function() {};
BicycleShop.prototype = {
  sellBicycle: function(model) {
    var bicycle = BicycleFactory.createBicycle(model);
    
    bicycle.assemble();
    bicycle.wash();
    
    return bicycle;
  }
};
其实很简单,就是讲可分离出来的部分分离出来。
再看一下没有使用简单工厂模式的代码:
var BicycleShop = function() {};
BicycleShop.prototype = {
  sellBicycle: function(model) {
    var bicycle;
    
    switch(model) {
      case 'The Speedster':
        bicycle = new Speedster();
        break;
      case 'The Lowrider':
        bicycle = new Lowrider();
        break;
      case 'The Comfort Cruiser':
      default:
        bicycle = new ComfortCruiser();
    }
    Interface.ensureImplements(bicycle, Bicycle);
    
    bicycle.assemble();
    bicycle.wash();
    
    return bicycle;
  }
};
很明显,就起到解耦的作用了!
二:工厂模式
真正的工厂模式与简单工厂模式的区别在于,它不是另外使用一个类或对象来创建自行车的,而是使用一个子类。
例子:
先创建一个抽象类,里面的createBicycle方法要子类来实现
var BicycleShop = function() {};
BicycleShop.prototype = {
  sellBicycle: function(model) {
    var bicycle = this.createBicycle(model);
    
    bicycle.assemble();
    bicycle.wash();
    
    return bicycle;
  },
  createBicycle: function(model) {
    throw new Error('Unsupported operation on an abstract class.');
  }
};
然后子类实现它的createBicycle方法:
var AcmeBicycleShop = function() {};
extend(AcmeBicycleShop, BicycleShop);
AcmeBicycleShop.prototype.createBicycle = function(model) {
  var bicycle;

  switch(model) {
    case 'The Speedster':
      bicycle = new AcmeSpeedster();
      break;
    case 'The Lowrider':
      bicycle = new AcmeLowrider();
      break;
    case 'The Flatlander':
      bicycle = new AcmeFlatlander();
      break;
    case 'The Comfort Cruiser':
    default:
      bicycle = new AcmeComfortCruiser();
  }

  Interface.ensureImplements(bicycle, Bicycle);
  return bicycle;  
};
另一个子类实现不同的createBicycle方法:
var GeneralProductsBicycleShop = function() {};
extend(GeneralProductsBicycleShop, BicycleShop);
GeneralProductsBicycleShop.prototype.createBicycle = function(model) {
  var bicycle;

  switch(model) {
    case 'The Speedster':
      bicycle = new GeneralProductsSpeedster();
      break;
    case 'The Lowrider':
      bicycle = new GeneralProductsLowrider();
      break;
    case 'The Flatlander':
      bicycle = new GeneralProductsFlatlander();
      break;
    case 'The Comfort Cruiser':
    default:
      bicycle = new GeneralProductsComfortCruiser();
  }

  Interface.ensureImplements(bicycle, Bicycle);
  return bicycle;
};
三:工厂模式的适用场合
我还不懂,以后多写代码再总结
 
四:另外一个例子:RSS阅读器
这个例子,有空用来加深理解看看就好了~
/* DisplayModule interface. */

var DisplayModule = new Interface('DisplayModule', ['append', 'remove', 'clear']);

/* ListDisplay class. */

var ListDisplay = function(id, parent) { // implements DisplayModule
  this.list = document.createElement('ul');
  this.list.id = id;
  parent.appendChild(this.list);
};
ListDisplay.prototype = {
  append: function(text) {
    var newEl = document.createElement('li');
    this.list.appendChild(newEl);
    newEl.innerHTML = text;
    return newEl;
  },
  remove: function(el) {
    this.list.removeChild(el);
  },
  clear: function() {
    this.list.innerHTML = '';
  }
};

/* Configuration object. */

var conf = {
  id: 'cnn-top-stories',
  feedUrl: 'http://rss.cnn.com/rss/cnn_topstories.rss',
  updateInterval: 60, // In seconds.
  parent: $('feed-readers')
};

/* FeedReader class. */

var FeedReader = function(display, xhrHandler, conf) {
  this.display = display;
  this.xhrHandler = xhrHandler;
  this.conf = conf;

  this.startUpdates();
};
FeedReader.prototype = {
  fetchFeed: function() {
    var that = this;
    var callback = { 
      success: function(text, xml) { that.parseFeed(text, xml); }, 
      failure: function(status) { that.showError(status); } 
    };
    this.xhrHandler.request('GET', 'feedProxy.php?feed=' + this.conf.feedUrl, 
        callback);
  },
  parseFeed: function(responseText, responseXML) {
    this.display.clear();
    var items = responseXML.getElementsByTagName('item');
    for(var i = 0, len = items.length; i < len; i++) {
      var title = items[i].getElementsByTagName('title')[0];
      var link = items[i].getElementsByTagName('link')[0];
      this.display.append('<a href="' + link.firstChild.data + '">' + 
          title.firstChild.data + '</a>');
    }
  },
  showError: function(statusCode) {
    this.display.clear();
    this.display.append('Error fetching feed.');
  },
  stopUpdates: function() {
    clearInterval(this.interval);
  },
  startUpdates: function() {
    this.fetchFeed();
    var that = this;
    this.interval = setInterval(function() { that.fetchFeed(); }, 
        this.conf.updateInterval * 1000);
  }
};

/* FeedManager namespace. */

var FeedManager = {
  createFeedReader: function(conf) {
    var displayModule = new ListDisplay(conf.id + '-display', conf.parent);
    Interface.ensureImplements(displayModule, DisplayModule);
    
    var xhrHandler = XhrManager.createXhrHandler();
    Interface.ensureImplements(xhrHandler, AjaxHandler);
    
    return new FeedReader(displayModule, xhrHandler, conf);
  }
};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2015-03-25 23:54  oadaM92  阅读(207)  评论(0编辑  收藏  举报