The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
If several Laravel classes construct the same implementation with new, changing that implementation means changing each caller. You can reduce that coupling by depending on an interface and letting Laravel’s service container resolve its bound implementation. That approach addresses a related object-creation problem, but it is not automatically the classic Factory Method design pattern—and new is not inherently bad.
What Factory Method means—and what it does not
In the classic Factory Method pattern, a creator delegates product creation to a method whose implementation can vary, traditionally through creator subclasses. The caller works with a product abstraction instead of choosing and constructing a concrete product itself.
Laravel’s service container can solve a similar coupling concern by resolving dependencies and mapping interfaces to implementations. It is a framework-managed dependency-resolution mechanism, however, not necessarily a literal GoF Factory Method. The distinction matters: use the name of the mechanism you actually have, rather than calling every object-returning method or container binding a factory method.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
How to avoid scattered construction in Laravel
Suppose several consumers instantiate new SmtpNotifier() directly. If you later want a different notifier, those callers know too much about the concrete class. When there is a genuine implementation choice, define an interface, bind it to the chosen implementation, and type-hint the interface in consumers Laravel resolves.
#1 Best Overall
1. Define the contract and implementation
<?php
namespace AppContracts;
interface Notifier
{
public function send(string $message): void;
}
<?php
namespace AppServices;
use AppContractsNotifier;
class SmtpNotifier implements Notifier
{
public function send(string $message): void
{
// Send the message using SMTP.
}
}
2. Register the interface binding
Laravel’s service-provider documentation places service bindings in a provider’s register method. For example, in an application service provider:
<?php
namespace AppProviders;
use AppContractsNotifier;
use AppServicesSmtpNotifier;
use IlluminateSupportServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(Notifier::class, SmtpNotifier::class);
}
}
With this binding, a request for Notifier can be fulfilled with SmtpNotifier. The binding removes the need for each consumer to name that implementation.
3. Type-hint the contract in a consumer
<?php
namespace AppServices;
use AppContractsNotifier;
class WelcomeMessage
{
public function __construct(private Notifier $notifier)
{
}
public function send(): void
{
$this->notifier->send('Welcome');
}
}
When Laravel constructs a framework-managed class such as a controller, it can resolve type-hinted dependencies through the container. You generally do not need to call the container manually for ordinary constructor injection in framework-managed entry points.
Choose the simplest creation mechanism that fits
Avoiding new is not an objective by itself. If a class always needs one straightforward concrete dependency and there is no meaningful variation, direct construction or ordinary constructor injection may be clearer than adding an interface, binding, and factory class. Laravel does not require an abstraction for every class.
Rank #3
When there is a real choice, compare who should make it and how often that choice can change:
| Mechanism | Who chooses the implementation? | When it fits | Trade-off |
|---|---|---|---|
Direct construction with new |
The caller | A simple, stable dependency with no meaningful implementation choice | Callers are coupled to the concrete class they construct. |
| Explicit factory | The factory, based on its creation rule or input | Creation logic or runtime selection is substantial enough to deserve a dedicated place | Adds a class and indirection; useful when it clarifies a changing creation rule, not merely to hide one constructor call. |
| Container binding and constructor injection | The container uses the registered mapping | A consumer should depend on a contract and Laravel can resolve it at a framework-managed entry point | Requires a binding for an interface and can make resolution less explicit if callers reach into the container dynamically. |
Constructor injection also gives tests a seam: a consumer typed to an interface can receive a substitute implementation without changing its own code. Prefer passing dependencies in through the constructor over resolving them dynamically inside the consumer when ordinary injection works.
Rank #4
Do not confuse service resolution with Eloquent model factories
Laravel Eloquent factories serve a different purpose: they define model attributes for database seeding and tests. The framework documents generating one with php artisan make:factory; factories are conventionally discovered, and models can access them through the HasFactory trait. They are useful for producing model data, not a synonym for a runtime Factory Method that selects service implementations.
Laravel documentation
These links describe Laravel 13.x. Check the documentation for your application’s Laravel version if its provider setup or conventions differ.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

