简单工厂模式

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

对不同类的实例化

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

复制代码
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 @   邢韬  阅读(30)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
历史上的今天:
2020-12-01 cesium polylines 位置参数
2018-12-01 可空类型 int?及?相关运算符
点击右上角即可分享
微信分享提示