Creational Patterns «Prev Next»

Lesson 5 Factory Method: motivation
Objective Write an abstract Vehicle Class

Write an Abstract Vehicle Class

In object-oriented design, you often want to write code that works with a general concept (like a Vehicle) without hard-coding which specific kind of vehicle you will use (like Car, Bus, or Bicycle). This is the practical value of polymorphism: client code can depend on a common interface while concrete subclasses provide different behavior.

For example, an abstract base class called Vehicle may have multiple subclasses such as Car, Bicycle, or Bus. Each subclass behaves differently (a Bus accelerates differently than a Car), but they all support the same public interface. That interface might include methods such as start(), stop(), and accelerate().

Because the client only depends on the Vehicle abstraction, the same client code can work with many different vehicle types. This is a major reason OOP systems remain extensible: you can add a new Motorcycle or Scooter subclass later without rewriting the client logic.

Why Object Creation Breaks Abstraction

Polymorphism protects your code from needing to know the exact type of an object during normal use. However, there is one moment when type knowledge tends to leak through abstraction: object creation.

In Java and C++, constructors are tightly coupled to concrete class names. When you write:


Vehicle v = new Car();

the client must know at compile time that it is creating a Car. That direct dependency is often fine in small programs, but in frameworks, libraries, or large applications it leads to:

Creational patterns address this problem by moving creation decisions to a dedicated location and exposing a stable API to clients. In this lesson, the key idea is: clients should rely on the abstract type (Vehicle) and allow a factory to decide which concrete subclass to instantiate.

Factory Method: Motivation

The Factory Method pattern defines an interface (or overridable method) for creating objects, but lets subclasses decide which concrete class to instantiate. The pattern is especially useful when:

  1. You do not know at compile time which specific subclass should be created.
  2. You want to defer the choice of created objects to subclasses or configuration.
  3. A class delegates work to helper objects and you want to remove explicit type knowledge from the delegator.

Modern Java ecosystems often solve similar problems with dependency injection (DI) containers, service loaders, or provider-based APIs. But the underlying concept remains the same: separate object construction from object use. Factories are a classic way to do that when you want the solution to be explicit, understandable, and framework-free.

Framework Example: Creating Documents Without Knowing Their Concrete Type

A common place where factories are needed is in frameworks that must create user-defined objects. Imagine a document framework for multiwindow editors. You might define an abstract Document class, and users of the framework could derive classes like TextDocument or HtmlDocument. Meanwhile, a framework component such as DocumentManager maintains a list of open documents.

If your framework rule is “every created document must be registered with the manager,” then creation and registration should happen together in one operation. That is where Factory Method fits naturally:


class DocumentManager
{
public:
  Document* NewDocument();

private:
  virtual Document* CreateDocument() = 0;
  std::list<Document*> listOfDocs_;
};

Document* DocumentManager::NewDocument()
{
  Document* pDoc = CreateDocument();
  listOfDocs_.push_back(pDoc);
  ...
  return pDoc;
}

Notice what changed: NewDocument() does not call new directly because the framework cannot predict the concrete document type. Instead, it calls CreateDocument(), a factory method. Subclasses override CreateDocument() and provide the concrete instantiation:


Document* GraphicDocumentManager::CreateDocument()
{
  return new GraphicDocument;
}

This structure keeps the framework code operating on the abstraction (Document) while pushing concrete type knowledge into extension points where it belongs.

Connecting the Idea Back to Vehicles

Your lesson objective is to write an abstract Vehicle class. That abstraction is the foundation that makes Factory Method possible. If client code depends on a stable Vehicle API, then your application can create different vehicles without rewriting the code that uses them.

In a typical design, you would:

That is the “motivation” for Factory Method: it preserves abstraction even at creation time.

Related Pattern: Abstract Factory for Vehicle Families

While Factory Method typically creates one “product” at a time, Abstract Factory creates families of related products. The code below demonstrates a “vehicle family” factory that can produce a Car and an SUV in a consistent style (Luxury vs Non-Luxury).

This example is useful because it shows how factories scale beyond a single creation call and become a way to manage product consistency across a system.

Abstract VehicleFactory Class


public abstract class VehicleFactory {
  public static final String LUXURY_VEHICLE = "Luxury";
  public static final String NON_LUXURY_VEHICLE = "Non-Luxury";

  public abstract Car getCar();
  public abstract SUV getSUV();
}

Concrete Factory Subclasses


public class LuxuryVehicleFactory extends VehicleFactory {
  public Car getCar() {
    return new LuxuryCar("L-C");
  }
  public SUV getSUV() {
    return new LuxurySUV("L-S");
  }
}

public class NonLuxuryVehicleFactory extends VehicleFactory {
  public Car getCar() {
    return new NonLuxuryCar("NL-C");
  }
  public SUV getSUV() {
    return new NonLuxurySUV("NL-S");
  }
}

Even though this is labeled as “Factory Method: motivation,” this factory-family example also helps you understand the next step: once the abstract base type exists (Vehicle), factories become a clean way to produce objects consistently, without making client code depend on concrete classes.

Factory Method - Exercise

In this exercise, you will write a class that uses the Factory Method pattern.
Factory Method - Exercise
SEMrush Software 5 SEMrush Banner 5