← All categories

Creational

Who creates objects, and how much the rest of the code has to know about it.

Every object has to be built by someone. When construction is scattered across the code base, each caller has to know which concrete class to pick, which arguments go where, and in which order to call setters. That knowledge spreads, and small changes to how something is made turn into edits in dozens of files.

Creational refactorings move that knowledge to one place. Sometimes that is a factory that picks the right class, sometimes a step-by-step builder for an object with many optional parts, and sometimes it is simply passing a ready-made object in instead of creating it inside.

You'll recognise it when

  • The same if/else that chooses a class appears in several places.
  • Constructors take long lists of positional arguments, several of them booleans or nulls.
  • Objects can exist half-built because callers set fields one by one.
  • Tests can't swap a collaborator because the class builds its own.

Example

A cinema app books tickets. Seat, snacks and 3D glasses are all optional.

Before
// Which boolean is the glasses? What does null mean here?
Ticket t = new Ticket("Dune", "21:30", "F12", true, false, 2, null);

// Elsewhere, a ticket with no seat chosen yet
Ticket walkIn = new Ticket("Dune", "21:30", null, false, false, 0, null);
After
Ticket t = Ticket.forShow("Dune", "21:30")
        .seat("F12")
        .glasses3d()
        .popcorn(2)
        .build();          // build() checks the combination is valid

Ticket walkIn = Ticket.forShow("Dune", "21:30").build();

Why it's better: Each option is named where it is used, defaults live in one place, and an invalid ticket is rejected when it is built rather than when it reaches the box office.

Ideas you'll practise

Factory MethodAbstract FactoryBuilderPrototypeSingleton (and when not to use it)Dependency Injection

Problems 14