简单工厂模式

简单工厂模式,又叫静态工厂模式,由一个工厂创建某一种对象的实例,主要用来创建同一种对象

对不同类的实例化

有一个需求,要创建登录提示框,登录的确认框,登录成功的提示框,因为逻辑不完全相同,所以我们写成三个类

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
}

 

posted @ 2021-12-01 21:14  邢韬  阅读(27)  评论(0编辑  收藏  举报