JavaScrip设计模式(四)——工厂模式和抽象工厂模式


前言


一. 工厂模式

// es5写法
function UserFactory(role){
  /**
    * @role 角色
    * @pages 角色对应能看到的页面
    */
  function User(role, pages){
    this.role = role;
    this.pages = pages;
  }
  switch(role) {
      case "superAdmin": 
        return new User("superAdmin", "1,2,3,4");
      break;
      case "admin": 
        return new User("admin", "1,2,3");
      break;
      case "editor": 
        return new User("*editor*", "1,2");
      break;
      default:
        throw new Error("参数错误!!!")
  }
}
var user1 = UserFactory('superAdmin');
var user2 = UserFactory('admin');
var user3 = UserFactory('editor');
var user4 = UserFactory('zhangsan');
console.log(user1); // {pages: "1,2,3,4", role: "superAdmin"}
console.log(user2); // {pages: "1,2,3", role: "admin"}
console.log(user3); // {pages: "1,2", role: "editor"}
console.log(user4); // Uncaught Error: 参数错误!!!

// es6 使用类的写法
class User{
  /**
    * @role 角色
    * @pages 角色对应能看到的页面
    */
  constructor(role, pages) {
    this.role = role;
    this.pages = pages;
  }
  static UserFactory(role){
    switch(role) {
        case "superAdmin": 
            return new User("superAdmin", "1,2,3,4");
        break;
        case "admin": 
            return new User("admin", "1,2,3");
        break;
        case "editor": 
            return new User("editor", "1,2");
        break;
        default:
            throw new Error("参数错误!!!")
    }
  }
}
var user1 = User.UserFactory('superAdmin');
var user2 = User.UserFactory('admin');
var user3 = User.UserFactory('editor');
// var user4 = User.UserFactory('zhangsan');
console.log(user1); // {pages: "1,2,3,4", role: "superAdmin"}
console.log(user2); // {pages: "1,2,3", role: "admin"}
console.log(user3); // {pages: "1,2", role: "editor"}
// console.log(user4); // Uncaught Error: 参数错误!!!

如上示例:一个后台管理页面,超级管理员(superAdmin)、管理员(admin)、编辑者(editor)分别有1234、123,12的页面权限,将其封装 在一个函数中,通过不同登陆人的状态获取对应的页面。即编写工厂函数,调用它,传入你期望的参数,获得对应的值。这就是工厂模式的一个简单应用了。

1:作用

由一个对象决定创建一种产品对象类的实例,主要用来创建同一对象

2:优点

只需要一个正常的参数,就可以获得所需要的数据,无需知晓具体创建的细节,可以快速创建大量相似对象,没有重复代码。

3:缺点

  1. 工厂模式函数内部包含了所有对象创建的逻辑和判断逻辑的代码,每次增加新的构造函数需要修改判断逻辑代码,相对来讲比较麻烦。
  2. 工厂模式函数内部的对象不是3个,而是10个甚至更多,会导致难以维护。
  3. 工厂模式函数创建的对象属于Object,无法区分对象类型,这也是工厂模式没有广泛使用的原因。

总结:所以创建对象数量少,对象的创建逻辑不复杂的时候使用工厂模式。

二、抽象工厂模式

class User{
  /**
  * @name 用户名
  * @role 权限
  * @pages 用户权限对应有的页面
  */
  constructor(name, role, pages){
    this.name = name;
    this.role = role;
    this.pages = pages;
  }
}
class SuperAdmin extends User{
  constructor(name){
    super(name, 'superAdmin', [1,2,3,4])
  }
}
class Admin extends User{
  constructor(name){
    super(name, 'admin', [1,2,3])
  }
}
class Editor extends User{
  constructor(name){
    super(name, 'editor', [1,2])
  }
}
function getUserPages(role){
  switch(role) {
    case "superAdmin": 
        return SuperAdmin;
    break;
    case "admin": 
        return Admin;
    break;
    case "editor": 
        return Editor;
    break;
    default:
        throw new Error("参数错误!!!")
  }
}
let userClass1 =  getUserPages('superAdmin');
console.log(userClass1); // 对应超级管理员的类
let user1 = new userClass1('张三');
console.log(user1);// {name: "张三", pages: [1, 2, 3, 4] ,role: "superAdmin"}

let userClass2 =  getUserPages('admin');
console.log(userClass2); // 对应管理员的类
let user2 = new userClass2('李四');
console.log(user2);// {name: "李四", pages: [1, 2, 3] ,role: "admin"}

let userClass3 =  getUserPages('editor');
console.log(userClass3); // 对应编辑者的类
let user3 = new userClass3('王五');
console.log(user3);// {name: "王五", pages: [1, 2] ,role: "Editor"}

上述代码效果图如下
在这里插入图片描述
如上示例:同样是一个后台管理页面,超级管理员(superAdmin)、管理员(admin)、编辑者(editor)分别有1234、123,12的页面权限,抽象工厂模式先写了一个用户(user)类,含有其他用户的共同属性,将超级管理员、管理员、编辑者分别写了一个类并继承用户类,最后依旧使用了一个方法switch的时候返回的是对应的类,区别开来。抽象工厂函数就是为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

1:定义

在工厂模式的加上一层抽象,工厂的工厂。只需要一个正常的参数,就可以获得所需要的数据,无需知晓具体创建的细节。
白话:抽象工厂模式并不直接生成示例,而是对产品类的创建。

2:优点

抽象工厂函数就是为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。


总结

该不该使用用工厂,就要看它是否带来大量不必要的复杂性,带来不必要的开销(不为了用模式而用模式)。抽象工厂模式就是如果你要使用工厂模式的情况下,里面switch有多个(如10个)的判断逻辑,并且逻辑比较复杂的话,就可以使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值