← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Abstract Factory Pattern

Code Quality PHP 5.0+ Intermediate
debt(d7/e5/b5/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate automated detection is 'no', and while phpstan is listed, it cannot reliably detect when you should be using Abstract Factory or when you're mixing incompatible product families. The code pattern (new ...Gateway && new ...Request from different providers) requires manual review or custom static analysis rules. Misuse — mixing objects from different families — compiles fine and often only manifests at runtime, though typically during testing rather than silently in production, so d7 rather than d9.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to 'introduce an Abstract Factory and inject it instead of instantiating objects directly,' which involves creating a factory interface, concrete factory implementations, updating all call sites that directly instantiate related objects, and wiring the factory through dependency injection. This typically touches multiple files within a component or module. It's not quite cross-cutting (e7) since it's usually localized to one subsystem's creation logic, but it's clearly more than a simple parameterized fix.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Abstract Factory applies across web, cli, and queue-worker contexts and is a creational design pattern that, once adopted, shapes how all product families are created and extended. Adding a new product type requires updating every concrete factory. It doesn't quite define the system's shape (b9/b7), but it imposes a persistent tax: every new product variant or family requires coordinated changes across factory interfaces and implementations, and developers must understand the pattern to work with the affected code.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field explicitly states that developers confuse Abstract Factory with Factory Method, believing them interchangeable. This is a well-documented gotcha in the patterns community. Factory Method creates a single product; Abstract Factory creates families of related products. Competent developers who know Factory Method will often reach for it when Abstract Factory is needed (or vice versa), and common_mistakes confirm overuse when only one product varies. It's not quite t7 because the distinction is well-covered in pattern literature, but it genuinely trips up intermediate developers.

About DEBT scoring →

Also Known As

abstract factory family factory

TL;DR

Creates families of related objects ensuring they are used together consistently without mixing implementations.

Explanation

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. Each concrete factory produces a consistent set of products (e.g., StripeGateway, StripeRequest, StripeResponse). This ensures that objects designed to work together are never mixed with incompatible ones. It is commonly used when systems must support multiple interchangeable configurations (e.g., payment providers, UI themes, database drivers). Unlike Factory Method, which creates a single product, Abstract Factory guarantees consistency across a full product family.

Common Misconception

Abstract Factory and Factory Method are interchangeable. Factory Method creates a single product, while Abstract Factory ensures a consistent family of related products is created together.

Why It Matters

Without Abstract Factory, systems can accidentally mix incompatible objects from different providers — these errors often compile but fail at runtime and are hard to trace.

Common Mistakes

  • Using Abstract Factory when only one product varies — adds unnecessary complexity.
  • Creating factories that return unrelated objects — defeats the purpose of product families.
  • Exposing concrete factories directly instead of injecting abstractions.
  • Mixing factory-created objects with manually instantiated ones.

Avoid When

  • Only one product type varies — use Factory Method instead.
  • Products are independent and do not need to be used together.
  • System has a single fixed implementation with no variation.
  • The abstraction adds more complexity than the variation justifies.

When To Use

  • Multiple related objects must always be used together.
  • System must support interchangeable product families (e.g., providers, themes).
  • You want to enforce compatibility between created objects.
  • Configuration should swap entire implementations, not individual classes.

Code Examples

💡 Note
All objects are created via the same factory, guaranteeing they belong to the same compatible family.
✗ Vulnerable
// ❌ Mixing incompatible product families
$gateway = new StripeGateway();
$request = new BraintreePaymentRequest(); // runtime mismatch
✓ Fixed
interface PaymentFactory {
    public function createGateway(): GatewayInterface;
    public function createRequest(Money $amount): RequestInterface;
    public function createResponse(array $data): ResponseInterface;
}

final class StripeFactory implements PaymentFactory {
    public function createGateway(): GatewayInterface {
        return new StripeGateway();
    }

    public function createRequest(Money $amount): RequestInterface {
        return new StripeRequest($amount);
    }

    public function createResponse(array $data): ResponseInterface {
        return new StripeResponse($data);
    }
}

// Usage
function processPayment(PaymentFactory $factory, Money $amount) {
    $gateway = $factory->createGateway();
    $request = $factory->createRequest($amount);

    $rawResponse = $gateway->send($request);

    return $factory->createResponse($rawResponse);
}

Added 16 Mar 2026
Edited 27 Mar 2026
Views 86
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 2 pings W 1 ping T 0 pings F 0 pings S 2 pings S 2 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 14 Perplexity 13 ChatGPT 11 Google 6 Scrapy 6 SEMrush 5 Ahrefs 4 Unknown AI 3 Bing 3 Claude 2 Majestic 1 Meta AI 1
crawler 64 crawler_json 5
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
If multiple related objects must always be used together, introduce an Abstract Factory and inject it instead of instantiating objects directly.
📦 Applies To
PHP 5.0+ web cli queue-worker
🔍 Detection Hints
new .*Gateway && new .*Request from different providers OR switch creating multiple related objects
Auto-detectable: ✗ No phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class Tests: Update


✓ schema.org compliant