Primitive Obsession

Using primitives instead of small objects for simple tasks.

“People new to objects are reluctant to use small objects for small tasks.” – Fowler & Beck

string email instead of Email email.

Signs of Use (Symptoms)

  • Many string or int parameters for things like phone, zip, currency.
  • Validation logic for a “type” is scattered everywhere (if email.includes('@')).
  • Constants like const USD = "USD" instead of an Enum or Value Object.

Why it is bad (Consequences)

  • Duplication: Same validation repeated in many places.
  • Type Safety: Easy to pass a customerId where orderId was expected (both are string).

Why it happens (Root Cause)

Creating a class for Email feels like overkill. It’s “just a string”.

When it might be okay (Exceptions)

  • Truly generic primitives (e.g., the actual ID string if there’s no behavior attached).

Explanation

Problem

You use string for email, phone, address, etc. Validation happens at the edges (controllers) or is duplicated.

The Flaw

The primitive has no inherent meaning. You can assign any string to an email variable.

Real world analogy

Using a generic brown box for everything. A box labeled “Fragile: Crystal Glasses” is much better than an unmarked box containing the same item.

Refactoring Solution

  • Replace Primitive with Object: Create Value Objects (e.g., Email, Money, ZipCode).
  • Replace Type Code with Subclasses/Strategy.

Pros and Cons (of the Antipattern)

Pros (Why people do it) Cons (The price you pay)
  • Less code initially
  • No type safety
  • Duplicated validation
  • Comparison

    • Related Antipatterns: Data Clumps.
    • Related Principles: DRY.

    Code example

    Typescript

    Bad (The Antipattern)

    Good (The Fix)

    PHP

    Bad (The Antipattern)

    Good (The Fix)