小白學習JavaScript設計模式(2)——工廠方法模式

在說工廠方法模式之前先說一下安全模式類

什麼是安全模式類,安全模式類就是說可以屏蔽使用這對類的錯誤使用造成的錯誤,這聽起來有點不容易理解,那下面舉一個例子。

現在我們創建了一個Dome類如下:

var Dome = function(text){
    this.text = text;
}
Dome.prototype = {
    show:function(){
        console.log(this.text);
    }
}

如果我們要使用這個Dome類必須要使用new關鍵字來執行(var d = new Dome()),但是有時往往會忽略掉new關鍵字(var d = Dome()),此時當我們調用Dome類的show()方法時會出現如下錯誤。

//Uncaught TypeError:Connot read property 'show' of undefined

我們有一種簡單的解決方案:在構造函數開始時先判斷當前的this指代是不是類(Dome),如果是則通過new關鍵字創建對象,如果不是說明類在全局域中執行,即只想window。代碼如下:

var Dome  = function(content){
    if(!(this instanceof Dome)){
        return new Dome(content);
    }
}

Dome.prototype = {
    show:function(){
        console.log("獲取成功");
    }
}

var d1 = Dome();
d1.show();  //獲取成功

//或者
var d2 = new Dome();
d2.show();  //獲取成功

 工廠方法模式

工廠方法模式是將實際創建的對象工作推遲到子類當中,這樣核心類就成了抽象類。

舉個例子:現在需要做一些課程培訓的廣告,包括JS、HTML、CSS三個部分,他們分別採用不同的背景顏色。如果按照原來的簡單工廠模式的思想,我們首先需要創建對應的3個類,如下:

//創建JS類
        var JS = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid red';
                document.getElementById("container").appendChild(div);
            })(content);
        };
        //創建JS類
        var HTML = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid yellow';
                document.getElementById("container").appendChild(div);
            })(content);
        };
        //創建JS類
        var CSS = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid green';
                document.getElementById("container").appendChild(div);
            })(content);
        };

function JobFactory(type, content) {
            switch (type) {
            case 'JS':
                return new Js(content);
            case 'HTML':
                return new HTML(content);
            case 'CSS':
                return new CSS(content);
            }
        }

我們可以看到這樣寫出來的代碼量很大,並且當每次要增加需求的時候我們都至少要修改兩個地方,這顯然降低了效率。

那麼接下來我們看一下工廠方法模式的優勢所在,直接上代碼:

var Factory = function (type, content) {
            if (this instanceof Factory) {
                var s = new this[type](content);
                return s;
            } else {
                return new Factory(type, content);
            }
            this.content = content;
        };
Factory.prototype = {
            JS: function (content) {
                //                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid green';
                    document.getElementById("container").appendChild(div);
                })(content);
            },
            CSS: function (content) {
                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid red';
                    document.getElementById("container").appendChild(div);
                })(content);
            },
            HTML: function (content) {
                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid yellow';
                    document.getElementById("container").appendChild(div);
                })(content);
            }
        }

        var data = [
            {
                type: 'HTML',
                content: "HTML"
            }, {
                type: 'CSS',
                content: "CSS模塊"
            }, {
                type: 'JS',
                content: "JS模塊"
            }, {
                type: 'JS',
                content: "JS模塊"
            }, {
                type: 'CSS',
                content: "CSS模塊"
            }
        ];
        for (var i = 0; i < data.length; i++) {
            Factory(data[i].type, data[i].content);
        }

直觀的看上去貌似代碼量比原來的還要多,那是因爲我們這裏顯示了5條數據,並且增加了安全模式驗證。

我們來分析一下代碼,看看有哪些不同的地方。

最大的不同是我們把所有的子類改成了一個工廠類的原型方法中,這樣做的好處可以減少代碼的污染,得到了很好的封裝,現在如果遇到了需求變更,我們只需要在這個工程類中增加或刪除對應的方法即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章