工厂模式与建造者模式

143 阅读2分钟

1.简单工厂模式

利用工厂函数,快速生成类的实例。对于生成的各个实例的区别,逻辑全写在一个工厂函数里。

  • 优点:只需要一个简单的参数,就能获取到需要的对象,而无需关心创建的具体细节。
  • 缺点:在工厂函数内包含了所有对象的创建逻辑和判断代码,每增加新的构造函数还需要修改判断逻辑代码,一旦创建的对象数量多,创建逻辑复杂,将会变得难以维护。
  • 适用于创建的对象数量较少,对象的创建逻辑不复杂时使用
class User {
  constructor(role, pages) {
    this.role = role
    this.visiblePages = pages
  }
​
  static userFactory(role) {
    const rolePagesMap = {
      superadmin: ['home', 'user-manage', 'auth-manage', 'news-manage'],
      admin: ['home', 'user-manage', 'news-manage'],
      editor: ['home', 'news-manage']
    }
    if(!Object.keys(rolePagesMap).includes(role)) throw new Error('RoleError: no such role!')
    return new this(role, rolePagesMap[role])
  }
}

2. 抽象工厂模式

不直接生成实例,而是用于对产品类簇的创建

// 基类
class User {
  constructor(name, role, pages) {
    this.name = name
    this.role = role
    this.visiblePages = pages
  }
​
  welcome() {
    alert('欢迎回来,', this.name)
  }
​
  // js中的 abstract 关键字目前没什么作用
  showData() {
    throw new Error('抽象方法必须被实现!')
  }
}
​
class SuperAdmin extends User {
  constructor(name) {
    super(name, 'superadmin', ['home', 'user-manage', 'auth-manage', 'news-page'])
  }
​
  // 抽象方法重写
  showData() {
    console.log('show superadmin-data')
  }
​
  // 拓展其它方法
  addAuth() {
    // ...
  }
​
  addUser() {
    // ...
  }
​
  deleteAuth() {
    // ...
  }
  // '''
​
}
​
class Admin extends User {
  constructor(name) {
    super(name, 'admin', ['hmme', 'user-manage', 'news-page'])
  }
​
  showData() {
    console.log('show admin-data')
  }
​
  addUser() {
    // ...
  }
}
​
class Editor extends User {
  constructor(name) {
    super(name, 'edtor', ['home', 'news-manage'])
  }
​
  showData() {
    Console.log('show editor-data')
  }
}
​
// 工厂函数
const getAbstractUserFactory(role) {
  switch(role) {
    case 'superadmin':
      return SuperAdmin
  case 'admin':
    return Admin
  case 'editor':
    return Editor
  default:
    throw new Error('RoleError: no such role!')
  }
}
​
// 抽象工厂,得到类
let UserClass = getAbstractUserFactory('superadmin')
​
let user = new UserClass('cc')

抽象工厂模式用于创建类簇,每个类可以很方便地进行单独的维护,耦合性低。而对于各类簇的共享成员,则可以在基类中添加。抽象工厂函数只用于获取相应的类,而不生成实例。

3. 建造者模式

建造者模式是一步一步的创建一个复杂的对象,它允许用户只通过制定复杂的对象的类型和内容就可以构建它们,而无需指定内部的具体构造细节。建造者模式将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

class NavBar {
  init() {
    console.log('init nav-bar')
  }
​
  getData() {
    console.log('get nav data')
  }
​
  render() {
    console.log('render nav-bar')
  }
}
​
class List {
  init() {
    console.log('init List')
  }
​
  getData() {
    console.log('get List data')
  }
​
  render() {
    console.log('render List')
  }
}
​
// 建造者类,处理过程
class Operator {
  async startBuild(builder) {
    await builder.init()
    await builder.getData()
    await builder.render()
  }
}
​
const op = new Operator()
op.startBuild(new NavBar())
op.startBuild(new List())
  • 优点:将一个复杂对象的构建层与其表示层分离,同样的构建过程可采用不同的表示。 对比工厂模式:
  • 工厂模式主要是为了创建对象实例或者类簇,关心的是最终产出;
  • 建造者模式关心的是创建这个对象的整个过程,甚至于创建对象的每一个细节。