簡單工廠模式,又叫靜态工廠模式,由一個工廠建立某一種對象的執行個體,主要用來建立同一種對象
對不同類的執行個體化
有一個需求,要建立登入提示框,登入的确認框,登入成功的提示框,因為邏輯不完全相同,是以我們寫成三個類
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
}