JS设计模式—— 工厂方法方法模式详解

637 阅读2分钟

背景介绍

这是学习设计模式的第十三章,学习的是[工厂方法模式]。(www.patterns.dev/posts/facto…)

关于设计模式前十二节的内容,可以关注React设计模式专栏获取更多内容。

极简释义

使用函数不使用new关键字创建对象

写在前面

工厂方法模式,我们可以使用一个函数创建对象,而不使用new关键字。

比如说我们程序中会有很多用户,每个用户都有姓有名,邮箱等属性,可以用工厂模式实现:

const createUser = ({ firstName, lastName, email }) => ({
  firstName,
  lastName,
  email,
  fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
});

const user1 = createUser({

**firstName**: "John",

lastName: "Doe",

email: "john@doe.com"

});

const user2 = createUser({

firstName: "Jane2",

lastName: "Doe2",

email: "jane@doe.com"

});

console.log(user1);//{...}
console.log(user2.fullName()); //Jane2 Doe2

现在我们就可以调用createUser来创建用户对象了,并且新对象调用fullName方法获取全名了。

在线调试

工厂方法模式在创建相对复杂些并且可配置的对象时是很有效的。另外当有些对象的依赖配置得出时,也可以使用工厂方法模式轻松地创建:

const createObjectFromArray = ([key, value]) => ({
  [key]: value,
});
 
createObjectFromArray(["name", "John"]); // { name: "John" }

总结

工厂方法模式对于创建多个共享属性且相对较小对象时是很有用的。工厂模式可以轻松地创建依赖环境或者用户配置的对象。

在JavaScript中,工厂方法模式仅仅是一个不使用new关键字,来创建对象的方法。ES6的箭头函数可以隐式返回一个简易的工厂方法。

通常情况下,使用工厂方法模式比使用new关键字更节约内存

上面的案例使用new关键字实现如下:

class User {
  constructor(firstName, lastName, email) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
  }
 
  fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}
 
const user1 = new User({
  firstName: "John",
  lastName: "Doe",
  email: "john@doe.com",
});
 
const user2 = new User({
  firstName: "Jane",
  lastName: "Doe",
  email: "jane@doe.com",
});

通过对比, 我们不难发现, 使用class方式来创建对象, 代码行数较多, 而且细想到class背后的实现原理也是构造函数来实现的, 在较小对象时, 还不如直接用函数来的简洁.

当然工厂方法对于属性较少的对象时, 会比较直观, 而对于属性较多和包含复杂逻辑的对象, 还是class更能让人清晰明了.

具体的使用场景还是要根据实际情况来判断----实事求是.

相关活动

本文正在参加「金石计划」