1. 程式人生 > >【JavaScript筆記設計模式】-工廠模式

【JavaScript筆記設計模式】-工廠模式

簡單工廠模式是由一個方法來決定到底要建立哪個類的例項, 而這些例項經常都擁有相同的介面. 這種模式主要用在所例項化的型別在編譯期並不能確定, 而是在執行期決定的情況。 說的通俗點,就像公司茶水間的飲料機,要咖啡還是牛奶取決於你按哪個按鈕。

var Car = (function () {
    var Car = function (model, year, miles) {
        this.model = model;
        this.year = year;
        this.miles = miles;
    };
    return
function (model, year, miles) { return new Car(model, year, miles); }; })(); var tom = new Car("Tom", 2009, 20000); var dudu = new Car("Dudu", 2010, 5000);

不好理解的話,我們再給一個例子:

var productManager = {};

productManager.createProductA = function () {
    console.log('ProductA');
}

productManager.createProductB 
= function () { console.log('ProductB'); } productManager.factory = function (typeType) { return new productManager[typeType]; } productManager.factory("createProductA");

如果還不理解的話,那我們就再詳細一點咯,假如我們想在網頁面裡插入一些元素,而這些元素型別不固定,可能是圖片,也有可能是連線,甚至可能是文字,根據工廠模式的定義,我們需要定義工廠類和相應的子類,我們先來定義子類的具體實現(也就是子函式):

var page = page || {};
page.dom = page.dom || {};
//子函式1:處理文字
page.dom.Text = function () {
    this.insert = function (where) {
        var txt = document.createTextNode(this.url);
        where.appendChild(txt);
    };
};

//子函式2:處理連結
page.dom.Link = function () {
    this.insert = function (where) {
        var link = document.createElement('a');
        link.href = this.url;
        link.appendChild(document.createTextNode(this.url));
        where.appendChild(link);
    };
};

//子函式3:處理圖片
page.dom.Image = function () {
    this.insert = function (where) {
        var im = document.createElement('img');
        im.src = this.url;
        where.appendChild(im);
    };
};

那麼我們如何定義工廠處理函式呢?其實很簡單:

page.dom.factory = function (type) {
    return new page.dom[type];
}

使用方式如下:

var o = page.dom.factory('Link');
o.url = 'http://www.cnblogs.com';
o.insert(document.body);

實際上在js裡面,所謂的建構函式也是一個簡單工廠。只是批了一件new的衣服. 我們扒掉這件衣服看看裡面。

通過這段程式碼, 在firefox, chrome等瀏覽器裡,可以完美模擬new.

function A( name ){
  this.name = name;
}

function ObjectFactory(){
  var obj = {},
  Constructor = Array.prototype.shift.call( arguments );
  obj.__proto__ =  typeof Constructor.prototype === 'number'  ? Object.prototype :  Constructor.prototype;
  var ret = Constructor.apply( obj, arguments );
  return typeof ret === 'object' ? ret : obj;
}
var a = ObjectFactory( A, 'mr mo' );
console.log ( a.name );  //mr mo

這段程式碼來自es5的new和構造器的相關說明, 可以看到,所謂的new, 本身只是一個物件的複製和改寫過程, 而具體會生成什麼是由呼叫ObjectFactory時傳進去的引數所決定的。

參考地址: