The Factory pattern centralizes object creation when constructors, configuration, or concrete classes become too noisy for callers.
When construction becomes a responsibility
Creating an object is sometimes simple. Calling new Money(1000, USD) is clear enough. But construction becomes a responsibility when it requires configuration, conditionals, external data, or several collaborators. If many classes know how to build the same object, construction logic spreads and becomes hard to change.
What a factory does
A factory gives object creation a name. A PaymentGatewayFactory can create the correct gateway for a tenant. A ReportExporterFactory can choose a PDF, CSV, or HTML exporter. The caller asks for what it needs and the factory hides the concrete construction details. This reduces coupling and keeps workflows focused on behavior.
Factory method vs factory class
A factory method is a method responsible for creating an object, often inside a class hierarchy. A factory class is a dedicated collaborator that creates objects for other parts of the system. In Laravel projects, factory classes are often more explicit and easier to inject. They also work well with configuration-driven applications.
Factories and the service container
Laravel service providers can act like factories for application services, but not every construction rule belongs directly in a provider. If object selection depends on runtime data, a dedicated factory is usually clearer. The provider can bind the factory, and the factory can use the container to build registered implementations.
Keeping factories small
A factory should not become a business workflow. It should decide what to create and how to create it. If it starts validating permissions, updating records, or sending notifications, responsibilities have drifted. Keep the factory near construction and let services handle the use case.
Testing factory behavior
Factory tests should prove that the right concrete implementation is returned for each input and that invalid input fails clearly. Workflow tests can then fake the factory or use a known implementation. This separation prevents object creation details from leaking into every test.
Where it fits
Factory pairs well with Strategy because a factory or resolver often chooses the correct strategy. It also pairs with Builder when the object needs many optional construction steps.
Internal reading path
This article is part of a connected OOP and design patterns series. Continue with these related guides:
- Builder Pattern for Readable Object Creation in PHP
- Dependency Injection in Laravel: Writing Flexible Services
- Strategy Pattern in PHP: Replacing Conditionals With Behavior
Practical checklist
- Name the responsibility before choosing a pattern.
- Prefer small contracts where behavior varies or external services are involved.
- Keep controllers at the edge and move workflows into named application code.
- Add tests around the behavior that is most likely to change.
- Use patterns to reduce coupling, not to make simple code look advanced.