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

工厂模式

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
相关推荐
故事还在继续吗14 小时前
设计模式完全指南
设计模式
桔筐14 小时前
Vue3 v-model 双向绑定导致循环触发的坑
前端·javascript·vue.js
Alice-YUE14 小时前
前端图片优化完全指南:从格式到加载的全面提速方案
前端·笔记·学习
fen_fen15 小时前
下载Chrome浏览器对应的Driver
前端·chrome
路光.15 小时前
ReferenceError:Can‘t find variable:structureClone
前端·javascript·html·vue2
前端那点事15 小时前
内存泄漏排查全指南:从场景识别到工具实操,新手也能上手
前端·vue.js
我这一生如履薄冰~15 小时前
浏览器多窗口同开一页面,数据同步更新(纯前端方案)
前端·javascript
Alice-YUE15 小时前
前端性能优化完全指南:从指标到实战
前端·学习·性能优化
Momo__15 小时前
Web Speech API 语音识别与合成详解
前端·javascript
曹牧15 小时前
Java Web:DispatcherServlet
java·开发语言·前端