Factory & Proxy
Pattern in Magento 2
Automatisch generierte Factories für neue Objekte, Proxies für Lazy Loading teurer Services — beide Patterns zusammen erklärt mit konkreten Anwendungsfällen und PHP 8.4.
Inhaltsverzeichnis
1. Factory Pattern: Warum kein new?
In Magento 2 gilt die Regel: Neue Objekte werden nicht mit new erstellt. Der Grund ist fundamental: new KlassenName() umgeht den DI-Container vollständig.
- Plugins (Interceptors) werden nicht auf das erzeugte Objekt angewendet
- Die konfigurierte Preference in di.xml wird ignoriert
- Virtual Types funktionieren nicht
- Der Shared/Non-Shared Status wird ignoriert
2. Automatisch generierte Factories
Magento 2 generiert Factories automatisch beim Ausführen von bin/magento setup:di:compile oder on-the-fly im Developer Mode. Konvention: Klassenname + "Factory" als Typ-Hinweis deklarieren:
Die generierte Factory sieht (vereinfacht) so aus:
3. Factories richtig verwenden
4. Factory mit initialen Daten
Factories akzeptieren ein optionales $data-Array als Konstruktor-Argument. Besser ist jedoch die explizite Setter-API:
5. Proxy Pattern: Lazy Loading für teure Objekte
Das Proxy Pattern schiebt die Erzeugung eines teuren Objekts auf, bis es wirklich gebraucht wird. Ein Proxy wird als Stellvertreter injiziert — er sieht nach außen genauso aus wie die echte Klasse, erzeugt die echte Instanz aber erst beim ersten Methodenaufruf:
6. Automatisch generierte Proxies
Proxies werden von Magento automatisch generiert. Zwei Wege der Konfiguration:
7. Session-Proxies: der wichtigste Anwendungsfall
Der häufigste Anwendungsfall für Proxies: Session-Objekte. Sie starten PHP-Sessions und beeinflussen HTTP-Response-Header. Werden sie beim Bootstrap instanziiert, entstehen Probleme mit Page-Caching. Session-Objekte immer als Proxy injizieren.
8. Wann einen Proxy verwenden?
- Session-Objekte: Immer! (
CustomerSession\Proxy,CheckoutSession\Proxy,CoreSession\Proxy) - Schwere Services: Klassen mit aufwendigen Bootstrap-Operationen im Konstruktor die nur selten gebraucht werden
- Zirkuläre Abhängigkeiten auflösen: Wenn A von B abhängt und B von A — einen als Proxy injizieren
- Nicht bei: Leichten Services die sowieso immer gebraucht werden — Proxy-Overhead nicht gerechtfertigt
Mironsoft
Magento 2 Performance & Architektur
Magento 2 Performance analysieren und optimieren?
Wir analysieren Session-Initialisierung, teure DI-Chains und unnötige Objekterzeugungen in Ihrem Magento-Shop und optimieren gezielt mit Factory und Proxy Patterns.
Factory-Analyse
Direktes new ClassName() finden und durch korrekte Factory-Nutzung ersetzen
Session-Proxies
Alle Session-Injektionen auf Proxy umstellen — Page-Cache-Probleme vermeiden
Lazy Loading
Schwere Services identifizieren und durch Proxy-Injection lazy machen
9. Zusammenfassung
Factory und Proxy sind zwei Patterns die den ObjectManager effizient nutzen. Factory für neue Objekte — niemals direkt new. Proxy für Lazy Loading — vor allem für Sessions und schwere Services. Beide werden von Magento automatisch generiert.
Factory & Proxy — Das Wichtigste auf einen Blick
Factory — Neue Objekte
Niemals new Klasse(). Immer $factory->create(). Auto-generiert als KlassennameFactory. Respektiert DI, Plugins, Preferences.
Proxy — Lazy Loading
Teure Klassen lazy instanziieren. Auto-generiert als Klassenname\Proxy. Via di.xml oder direkt als Typ-Hinweis. Pflicht für Session-Objekte.
Session-Proxy
Immer CustomerSession\Proxy statt direkter Session. Gilt für alle Session-Klassen. Verhindert frühzeitige Session-Initialisierung und Page-Cache-Probleme.
setup:di:compile
Nach jeder di.xml-Änderung: bin/magento setup:di:compile. Generiert alle Factories, Proxies und Interceptors. Im Developer Mode on-the-fly generiert.
10. FAQ: Factory & Proxy in Magento 2
1 Muss ich Factories selbst schreiben?
KlassennameFactory als Typ-Hinweis deklarieren → Magento generiert automatisch in generated/code/. Developer Mode: on-the-fly. Production: bin/magento setup:di:compile.2 Was passiert bei direktem new ClassName()?
$factory->create() verwenden.3 Wann einen Proxy verwenden?
CustomerSession\Proxy). Sinnvoll: schwere Services die nur manchmal gebraucht werden. Zirkuläre Abhängigkeiten auflösen. Nicht für leichte Services die immer gebraucht werden.4 Warum Session nicht direkt injizieren?
5 Wie erstelle ich eine manuelle Factory?
ObjectManagerInterface injiziert und in create() aufruft. Name muss auf Factory enden. In di.xml als Preference für die auto-generierte Factory registrieren.6 Factory für ein Interface erstellen?
PostInterfaceFactory wird auto-generiert wenn PostInterface per Preference an Post gebunden ist. Factory erstellt die konkrete Klasse, gibt Interface-Typ zurück.7 Wie löst Proxy zirkuläre Abhängigkeiten auf?
8 Factory vs. Proxy — der Unterschied?
create() für Non-Injectable Objects. Proxy: Lazy-Wrapper für Injectable Objects — einmalige Instanz, verzögerte Initialisierung. Factory für neue Objekte, Proxy für späte Initialisierung.9 Nach Factory-Nutzung setup:di:compile nötig?
bin/magento setup:di:compile nötig. Generierte Dateien in generated/code/ — niemals manuell bearbeiten.10 Proxy für finale Klassen möglich?
final class kann nicht erweitert werden. Lösung: eigene Wrapper-Klasse mit der finalen Klasse als Dependency (Komposition statt Vererbung).