JavaScript 设计模式学习 Factory

复制代码 代码如下:

  /* DisplayModule interface. */

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

  /* ListDisplay class. */

  //通过接口实现工厂,这是通过List方式显示RSS

  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. */

  //工厂管理器,这里可以根据传进来的参数选择具体的Display

  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);

  }

  };

  =====================================================

  另一个自行车工厂的例子:

  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.');

  }

  };

  /* AcmeBicycleShop class. */

  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;

  };

  /* GeneralProductsBicycleShop class. */

  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;

  };

  /* Usage. */

  

复制代码 代码如下:

  var alecsCruisers = new AcmeBicycleShop();

  var yourNewBike = alecsCruisers.sellBicycle('The Lowrider');

  var bobsCruisers = new GeneralProductsBicycleShop();

  var yourSecondNewBike = bobsCruisers.sellBicycle('The Lowrider');