天天看點

簡單工廠模式

簡單工廠模式,又叫靜态工廠模式,由一個工廠建立某一種對象的執行個體,主要用來建立同一種對象

對不同類的執行個體化

有一個需求,要建立登入提示框,登入的确認框,登入成功的提示框,因為邏輯不完全相同,是以我們寫成三個類

const LoginAlter = function (text) {
    this.context = text
}
// 為什麼方法很多時候都要寫在prototype裡,而不直接寫在LoginAlter中呢
// 因為我們可能建構很多個LoginAlter的執行個體,如果直接寫在對象了,每次執行個體化就都會建立一遍,浪費記憶體
// 但是如果我們寫在原型中,執行個體化的時候是不會單獨建立的,調用直接找到原型裡,就可以實作共用了
LoginAlter.prototype.show = function () {
    // 顯示警示框
}
// 登入不規範警示
const userNameAlert = new LoginAlter("使用者名不能多于16個字元")
=============================================================================================================
// 密碼錯誤登入确認框
const LoginConfirm = function (text) {
    this.context = text
}
LoginConfirm.prototype.show = function () {
    // 顯示确認框
}
// 登入錯誤确認重新登入
const loginFailConfrim = new LoginAlter("登入密碼錯誤")
=============================================================================================================
// 登陸成功提示框
const LoginPrompt = function (text) {
    this.context = text
}
LoginConfirm.prototype.show = function () {
    // 顯示提示框
}      

但當類似的需求變多時,越來越多的類,很難記,怎麼才能放在一起呢?

可以采用簡單工廠模式進行封裝

const PopFactory = function (name, text) {
    switch(name){
        case "alter":
            return new LoginAlter(text)
        case "confirm":
            return new LoginConfirm(text)
        case "prompt":
            return new LoginPrompt(text)
    }
}      

建立相似對象

上述三個類雖然封裝起來了便于使用,但是這三個類相似度很高,是以可以用另一種簡單工廠模式建立一個對象,通過建立一個新的對象,然後包裝增強其屬性和功能來實作

const createPop = function (type, text) {
    let o = new Object()
    o.context = text
    o.show = function (text) {
        alert(text)
    }
    if(type === "alter"){
        // 警示框差異部分
    }
    if(type === "prompt"){
        // 提示框差異部分
    }
    if(type === "confirm"){
        // 确認框差異部分
    }
    return o
}      

安全的工廠方法

為了保證安全,防止忘記或使用錯誤,沒有通過new建立執行個體,導緻this指向外部造成污染,應使用安全模式建立,直接看代碼很好了解

const Demo = function () {
    if(!(this instanceof Demo)){
        return new Demo()
    }
}      

有時,因為需求一直變化,導緻使用不同類的工廠模式要一直重構,一直添加建立新的類,修改switch,并非一個很好的方式

我們可以借用原型的方式的方式添加,更為直覺簡潔

// 安全的工廠方法
const Factory = function (type, content) {
    if(this instanceof Factory){
        let s = new this[type](content)
        return s
    }else{
        return new Factory(type, content)
    }
}      

在原型上添加初始不同的對象

Factory.prototype = {
    Java: function (content) {
        // Java
    },
    JavaScript: function (content) {
        // JavaScript
    },
    UI: function (content) {
        // 注意,若不用安全模式,此處this就可能會指向全局,造成安全隐患
        this.content = content; //此處不加分号,會預設執行content(),閉包反而成了個累贅
        (function (content) {
            let div = document.createElement("div")
            div.innerHTML = content
            div.style.border = "1px solid red"
            document.getElementById("container").appendChild(div)
        })(content)
    },
    php: function (content) {
        // php
    },
}      

建立一個執行個體,如下圖,建立成功

const test = new Factory("UI", "UI training courses")      
簡單工廠模式

若此時需要添加一個Python的需求,隻需要在原型上添加即可

Factory.prototype.python = function(content){
    this.content = content
}      
簡單工廠模式
上一篇: 對象
下一篇: 數組