背景介绍
这是学习设计模式的第十三章,学习的是[工厂方法模式]。(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更能让人清晰明了.
具体的使用场景还是要根据实际情况来判断----实事求是.
相关活动
本文正在参加「金石计划」