Interested in our next book? Learn more about Building Large-scale JavaScript Web Apps with React

Design Pattern

Factory Pattern

With the factory pattern we can use factory functions in order to create new objects. A function is a factory function when it returns a new object without the use of the new keyword!

Say that we need many users for our application. We can create new users with a firstName, lastName, and email property. The factory function adds a fullName property to the newly created object as well, which returns the firstName and the lastName.

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

Perfect! We can now easily create multiple users by invoking the createUser function.

index.js
1const createUser = ({ firstName, lastName, email }) => ({
2 firstName,
3 lastName,
4 email,
5 fullName() {
6 return `${this.firstName} ${this.lastName}`;
7 }
8});
9
10const user1 = createUser({
11 firstName: "John",
12 lastName: "Doe",
13 email: "[email protected]"
14});
15
16const user2 = createUser({
17 firstName: "Jane",
18 lastName: "Doe",
19 email: "[email protected]"
20});
21
22console.log(user1);
23console.log(user2);

The factory pattern can be useful if we’re creating relatively complex and configurable objects. It could happen that the values of the keys and values are dependent on a certain environment or configuration. With the factory pattern, we can easily create new objects that contain the custom keys and values!

const createObjectFromArray = ([key, value]) => ({
  [key]: value,
});

createObjectFromArray(["name", "John"]); // { name: "John" }

Pros

The factory pattern is useful when we have to create multiple smaller objects that share the same properties. A factory function can easily return a custom object depending on the current environment, or user-specific configuration.


Cons

In JavaScript, the factory pattern isn’t much more than a function that returns an object without using the new keyword. ES6 arrow functions allow us to create small factory functions that implicitly return an object each time.

However, in many cases it may be more memory efficient to create new instances instead of new objects each time.

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: "[email protected]",
});

const user2 = new User({
  firstName: "Jane",
  lastName: "Doe",
  email: "[email protected]",
});

References