The Factory Pattern: Let Someone Else Worry About Construction

2026-04-24

You've used the Builder pattern for complex objects with many optional parameters. The Factory pattern solves a different problem: when the type of object you need depends on runtime conditions, and you don't want calling code to know the construction details.

Consider a notification system. You need to send alerts via email, SMS, Slack, or push notifications depending on user preferences:

Without a factory (the mess):

function sendAlert(user, message) {
  if (user.prefersEmail) {
    const smtp = new SmtpClient(config.smtp);
    const email = new EmailNotification(smtp, user.email);
    email.send(message);
  } else if (user.prefersSlack) {
    const token = vault.getSecret('slack-token');
    const slack = new SlackNotification(token, user.slackId);
    slack.send(message);
  } else if (user.prefersSms) {
    const twilio = new TwilioClient(config.sid, config.authToken);
    const sms = new SmsNotification(twilio, user.phone);
    sms.send(message);
  }
}

Every place that sends notifications now carries the burden of knowing how to construct every notification type. Add a new channel? Hunt down every call site.

With a factory:

class NotificationFactory {
  create(user) {
    switch (user.preferredChannel) {
      case 'email': return new EmailNotification(this.smtp, user.email);
      case 'slack': return new SlackNotification(this.slackToken, user.slackId);
      case 'sms':   return new SmsNotification(this.twilio, user.phone);
      default:      return new EmailNotification(this.smtp, user.email);
    }
  }
}

// Calling code becomes trivial
function sendAlert(user, message) {
  const notification = notificationFactory.create(user);
  notification.send(message);
}

The calling code doesn't know or care which concrete type it gets. It just calls send(). This works because all notification types share a common interface.

When to use a factory vs. direct construction:

Rule of thumb: If you see the same if/else or switch block selecting a type in 3+ places, extract a factory. Even in 1 place, a factory pays off once you hit 4+ branches — it keeps the selection logic testable in isolation and stops it from tangling with business logic.

Factories also make testing dramatically easier. Need to test sendAlert? Inject a factory that returns a mock notification. No SMTP server, no Twilio credentials, no Slack tokens in your test suite.

See it in action: Check out How to enter your subconscious mind to re-write your paradigm - Dr. Joe Dispenza (Meditation) by MindsetVibrations to see this theory applied.
Key Takeaway: Use the Factory pattern to centralize "which type do I need?" decisions in one place, keeping calling code clean, testable, and closed to modification when new types are added.

All newsletters