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

工厂模式

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
相关推荐
brief of gali几秒前
记录一个奇怪的前端布局现象
前端
小白不太白9501 小时前
设计模式之 观察者模式
观察者模式·设计模式
Json_181790144801 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing1 小时前
React核心功能详解(一)
前端·react.js·前端框架
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆2 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China2 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q2 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge