{
    "slug": "proxy_pattern",
    "term": "Proxy Pattern",
    "category": "quality",
    "difficulty": "intermediate",
    "short": "Provides a surrogate object that controls access to another object, adding indirection for lazy loading, caching, logging, or access control.",
    "long": "The Proxy pattern places an intermediary in front of a real object, implementing the same interface. Types: Virtual Proxy (defers expensive object creation until needed — lazy loading), Caching Proxy (caches results of operations on the real object), Protection Proxy (enforces access control), and Remote Proxy (represents an object in a different process or server). In PHP, Doctrine ORM uses virtual proxies for lazy-loaded entities. The Proxy differs from Decorator in intent: Decorator adds behaviour, Proxy controls access. PHP's magic methods (__get, __call) enable dynamic proxy creation.",
    "aliases": [
        "proxy",
        "virtual proxy",
        "protection proxy",
        "caching proxy"
    ],
    "tags": [
        "design-pattern",
        "oop",
        "structural"
    ],
    "misconception": "Proxy and decorator patterns are interchangeable. Proxies control access to an object (lazy loading, caching, access control) while decorators add behaviour. A proxy typically has a reference to the real subject from construction; a decorator receives it via injection.",
    "why_it_matters": "A proxy controls access to another object — it can add caching, logging, access control, or lazy initialisation transparently without changing the real object or its callers.",
    "common_mistakes": [
        "Not implementing the same interface as the real subject — callers must change to use the proxy.",
        "Proxy that adds logic the real object should have — the proxy should be transparent infrastructure, not business logic.",
        "Virtual proxies that initialise the real object eagerly — defeating the lazy loading purpose.",
        "Confusing proxy (same interface, controlled access) with decorator (same interface, added behaviour) — they serve different purposes."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "decorator_pattern",
        "lazy_loading",
        "caching"
    ],
    "prerequisites": [
        "interfaces",
        "lazy_loading",
        "decorator_pattern"
    ],
    "refs": [
        "https://refactoring.guru/design-patterns/proxy"
    ],
    "bad_code": "// Direct access — no caching, no access control:\nclass ReportService {\n    public function getExpensiveReport(int $id): Report {\n        return $this->db->runHeavyQuery($id); // Called every time\n    }\n}\n// A CachingReportProxy would intercept and cache without changing ReportService",
    "good_code": "interface Image {\n    public function render(): string;\n}\n\nclass RealImage implements Image {\n    public function __construct(private string $path) {\n        $this->loadFromDisk(); // expensive\n    }\n    public function render(): string { return \"<img src='{$this->path}'>\"; }\n}\n\n// Lazy-loading proxy — defers expensive load until render() is first called\nclass LazyImage implements Image {\n    private ?RealImage $real = null;\n    public function __construct(private string $path) {}\n    public function render(): string {\n        $this->real ??= new RealImage($this->path);\n        return $this->real->render();\n    }\n}",
    "quick_fix": "Use a proxy when you need to control access to an object (access control, logging, lazy initialisation) without changing its interface",
    "severity": "low",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/proxy_pattern",
        "html_url": "https://codeclaritylab.com/glossary/proxy_pattern",
        "json_url": "https://codeclaritylab.com/glossary/proxy_pattern.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Proxy Pattern](https://codeclaritylab.com/glossary/proxy_pattern) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/proxy_pattern"
            }
        }
    }
}