Verärgert über Tonnen von Klassen für DI in Konstrukteuren von Magento 2 - gibt es einen besseren Weg?

8

Zu diesem Zeitpunkt ärgere ich mich darüber, in meinen Modulen massenhaft ähnliche Konstruktoren wie die folgenden zu schreiben.

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\Registry $registry,

    /* ... */

    \Foo\Bar\Model\Baz $baz,

    /* ... */

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->registry = $registry;

    /* ... */

    $this->baz = $baz;

    /* ... */

    /* some awesome stuff */
}

In vielen, vielen Fällen benötige ich überall in meinem Modul Instanzen derselben Klassen.

Ich fragte mich also, ob es akzeptabel wäre, eine oder zwei zentrale Hilfsklassen zu verwenden, die die erforderlichen Klassen bereitstellen, anstatt sie in jedem einzelnen Konstruktor zu definieren.

Dies bedeutet ein Muster wie dieses:

Helferklasse

namespace Foo\Bar\Helper

class Main
{
    protected $baz;



    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,

        /* ... */

        \Foo\Bar\Model\Baz $baz,

        /* ... */
    ) {
        $this->registry = $registry;

        /* ... */

        $this->baz = $baz;

        /* ... */

        /* some awesome stuff */
    }



    public function getBazInstance()
    {
        return $this->baz;
    }
}

Der kürzere Konstruktor

public function __construct(

    \Foo\Bar\Helper\Main $mainHelper,

    \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
    \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
    array $data = []
) {
    $this->mainHelper = $mainHelper;

    /* some awesome stuff */
}

Zum jetzigen Zeitpunkt bin ich mir nicht sicher, ob ich mich in Zukunft mit großen Nachteilen aus dieser Struktur auseinandersetzen muss. Wäre dies ein akzeptabler Weg, um die Anzahl der DI-Definitionen zu reduzieren?

bukart
quelle

Antworten:

7

Check out \Magento\Framework\Model\Context, auf das in Ihrem Beispiel verwiesen wird. Was Sie beschreiben, ist genau das, was es tut. Magento verwendet ähnliche ContextObjekte im gesamten Kern, um DI-Listen zu verkürzen.

Das einzige, was zu beachten ist, ist, dass dies nicht dazu verwendet werden sollte, schlechte architektonische Entscheidungen zu verbergen . Sie sollten überlegen, ob jede der Klassen, die Sie für Ihr gesamtes Modul benötigen, wirklich erforderlich ist, und wenn ja, ob es eine alternative Möglichkeit gibt, Ihren Code so zu organisieren, dass dasselbe Ziel besser erreicht wird. Es ist einfach, unbeabsichtigte Leistungsprobleme einzuführen.

Ryan Hoerr
quelle
Nun ja ... es sollte nicht verwendet werden, um "schlechte architektonische Entscheidungen zu verbergen". Mein größter Punkt ist die Anzahl der Helfer, die ich verwenden muss (meine eigenen und Kernhelfer). Die Kontextklassen schienen mir genau das zu tun, was Sie gesagt haben. Ich war mir einfach nicht sicher. thx 4 Beratung
bukart
Für Laien sind ContextKlassen Magento-Klassen, die ganze Abschnitte von Magento umfassen? Wird der Kategoriekontext dabei helfen, das Hinzufügen / Bearbeiten / Entfernen / Anzeigen von Kategorien zu verwalten, ohne dass mehrere Klassen importiert werden müssen, um dieselbe Aktion auszuführen?
MackieeE
@ MackieeE Nein, nicht ganz. Sie umfassen einige der Magento-Abhängigkeiten für die jeweilige Klasse, die Sie betrachten. Sie sind normalerweise eher abstrakt / weit oben in der Vererbungskette und nicht spezifisch für eine bestimmte Endklasse (wie Kategorie). Wenn Sie sich das ansehen \Magento\Catalog\Model\Category, werden Sie feststellen, dass es dasselbe enthält, das \Magento\Framework\Model\Contextich erwähnt habe - es gibt eigentlich überhaupt nichts über Kategorien. Sie suchen ein Repository - schauen Sie sich das an \Magento\Catalog\Api\CategoryRepositoryInterface.
Ryan Hoerr
4

Ich bin mir ziemlich sicher, dass Sie in diesem Fall nicht der einzige sind, und irgendwie verstehe ich vollkommen, warum Sie darüber nachgedacht haben.

Für mich ist das Hauptproblem, das ich bei einem solchen Ansatz sehe, dass Sie einen der Hauptvorteile von Dependency Injection verlieren, nämlich sofort zu wissen, wovon Ihre Klasse abhängt, wenn Sie den Konstruktor überprüfen.

Ein weiterer wichtiger Vorteil von Dependency Injection besteht darin, dass das Testen von Code in einem automatisierten Framework einfacher wird. In Ihrem Fall ist das definitiv ein Nachteil.

Das sind die beiden Gründe, die auftauchen, aber es kann noch mehr geben.

EDIT: Ich werde nur ein Zitat von Alan Kent (der Teil von Magento ist) hinzufügen, das Sie in den Kommentaren dieser Frage finden können :

Ich rate generell davon ab, Methoden in eine Hilfsklasse zu werfen, die nicht verwandt sind. Es ist besser, separate Klassen zu haben, die reale Zwecke darstellen. Oder verwenden Sie statische Methoden. In diesem Fall ist kein Konstruktor erforderlich (der aufrufende Code ist dafür verantwortlich, Handles für die erforderlichen Datenstrukturen zu erhalten).

Raphael beim digitalen Pianismus
quelle
Ich stimme den oben genannten Gründen voll und ganz zu. Als Magento-Neuling scheint es jedoch eine große Lernkurve zu geben, um zu lernen, welche Klassen erforderlich und voneinander abhängig sind, bevor Sie mit der Entwicklung beginnen können.
MackieeE