Creational Virtual Constructor

Factory Method

Factory Method delegates object creation to a method that subclasses can override, so a base class can work with products whose exact type it doesn't need to know.

Complexity
Popularity

Problem

A logistics module starts out delivering only by road, so Logistics.planDelivery() builds a Truck object right inside its own method body. Months later, sea shipping is added. Every place that constructed a Truck directly now needs an if/else or switch on delivery mode, and that branching logic tends to get copy-pasted into every method that needs a transport rather than living in one place.

The underlying issue is that the class doing the useful work - planning the delivery, tracking it, logging it - is welded to one specific concrete class it happens to instantiate, so extending it to a new mode of transport means editing code that has nothing to do with that new mode conceptually.

Solution

Pull the new Truck(...) call out of the method body and into its own method - the factory method - and have the rest of the class call that method instead of a constructor directly. The base class only knows that the factory method returns something implementing a common Transport interface; it never names a concrete class.

Each delivery mode then becomes a subclass that overrides just the factory method: RoadLogistics returns a Truck, SeaLogistics returns a Ship. All the shared logic - planning, tracking, logging - stays untouched in the base class and automatically works with whatever concrete product the subclass decides to hand back.

When to Use

  • Reach for Factory Method when a class can't know in advance the exact type of object it will need to create - that decision belongs to a subclass or is resolved at runtime.
  • It's a natural fit when you're building a library or framework and want callers to be able to plug in their own product types without modifying your internal code.
  • Use it when several classes share almost identical logic and differ only in which kind of object they instantiate at one specific point.

Real-World Examples

  • document.createElement(tag) - the browser returns different concrete element classes (HTMLButtonElement, HTMLInputElement) behind the same Element interface, chosen by the tag argument.
  • Java's Calendar.getInstance() - returns a locale-appropriate concrete calendar subclass (Gregorian, Buddhist, Japanese) without the caller ever choosing the class directly.
  • Logger factories in frameworks like Log4j/SLF4J - LoggerFactory.getLogger() hands back a concrete logger implementation appropriate for the configured backend, behind one common Logger interface.