【设计模式】工厂模式和抽象工厂模式

工厂模式

js 复制代码
function User(role, pages) {
    this.role = role;
    this.pages = pages;
}

// new User('admin', ['home', 'user', 'setting']);
// new User('user', ['home', 'user']);
// new User('guest', ['home']);

function UserFactory(role) {
    switch (role) {
        case 'admin':
            return new User(role, ['home', 'user', 'setting']);
            break;
        case 'user':
            return new User(role, ['home', 'user']);
            break;
        case 'guest':
            return new User(role, ['home']);
            break;
        default:
            throw new Error('未知角色')
    }
}

es6 的写法:

js 复制代码
class User {
    constructor(role, pages) {
        this.role = role;
        this.pages = pages;
    }
    static getInstance(role) {
        switch (role) {
            case 'admin':
                return new User(role, ['home', 'user', 'setting']);
                break;
            case 'user':
                return new User(role, ['home', 'user']);
                break;
            case 'guest':
                return new User(role, ['home']);
                break;
            default:
                throw new Error('未知角色')
        }
    }
}

User.getInstance('admin'); // {role: 'admin', pages: ['home', 'user', 'setting']}

简单工厂的优点在于,你只需要一个正确的参数,就可以获取到你所需要的对象,而无需知道其创建的具体细节。

但是在函数内包含了所有对象的创建逻辑和判断逻辑的代码,每增加新的构造函数还需要修改判断逻辑代码。当我们的对象不是上面的3个而是10个或更多时,这个函数会成为一个庞大的超级函数,变得难以维护。

所以,简单工厂只能作用于创建的对象数量较少,对象的创建逻辑不复杂时使用。

抽象工厂模式

js 复制代码
class User {
    constructor(name, role, pages) {
        this.name = name;
        this.role = role;
        this.pages = pages;
    }

    welcome() {
        console.log(`欢迎${this.name}使用本系统`)
    }

    showPage() {
        // js 中没有内置的 abstract
        throw new Error(`请实现 showPage 方法`)
    }
}

class SuperAdmin extends User {
    constructor(name) {
        super(name, 'superAdmin', ['home', 'user', 'setting']);
    }

    showPage() {
        console.log(`超级管理员拥有以下页面:${this.pages.join(' ')}`)
    }

    addUser() {
        console.log(`添加用户`)
    }

    addRight() {
        console.log(`添加权限`)
    }
}

class Editor extends User {
    constructor(name) {
        super(name, 'editor', ['home', 'user']);
    }

    showPage() {
        console.log(`编辑拥有以下页面:${this.pages.join(' ')}`)
    }

}
function getAbstractUserFactory(role) {
    switch (role) {
        case 'superAdmin':
            return SuperAdmin;
        case 'editor':
            return Editor;
        default:
            throw new Error(`没有找到对应的角色`)
    }
}
const userClass = getAbstractUserFactory('editor');
const user = new userClass('张三');
user.showPage(); // 编辑拥有以下页面:home user
相关推荐
一枚前端小能手5 分钟前
「周更第3期」实用JS库推荐:Lodash
前端·javascript
艾小码5 分钟前
Vue组件到底怎么定义?全局注册和局部注册,我踩过的坑你别再踩了!
前端·javascript·vue.js
Cyan_RA912 分钟前
计算机网络面试题 — TCP连接如何确保可靠性?
前端·后端·面试
谢尔登12 分钟前
【CSS】层叠上下文和z-index
前端·css
鹏多多13 分钟前
前端复制功能的高效解决方案:copy-to-clipboard详解
前端·javascript
AryaNimbus15 分钟前
你不知道的 Cursor系列(三):再也不用死记硬背 Linux 命令,终端 Cmd+K 来帮你!
前端·ai编程·cursor
uhakadotcom17 分钟前
Rollup 从0到1:TypeScript打包完全指南
前端·javascript·面试
Mintopia23 分钟前
实时语音转写 + AIGC:Web 端智能交互的技术链路
前端·javascript·aigc
2503_9284115625 分钟前
9.15 ES6-变量-常量-块级作用域-解构赋值-箭头函数
前端·javascript·es6
Pedantic26 分钟前
SwiftUI ShareLink – 显示分享表单的使用
前端