Terganggu oleh banyak kelas untuk DI dalam konstruktor Magento 2 - apakah ada cara yang lebih baik?

8

Pada saat ini saya kesal menulis konstruktor serupa secara massal seperti berikut dalam modul saya.

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 */
}

Dalam banyak banyak kasus saya membutuhkan instance dari kelas yang sama di seluruh modul saya.

Jadi saya bertanya pada diri sendiri, apakah itu akan menjadi cara yang dapat diterima untuk menggunakan satu atau dua kelas pembantu pusat, yang menyediakan kelas yang diperlukan, daripada mendefinisikan mereka di setiap konstruktor tunggal.

Ini berarti pola seperti ini:

Kelas Pembantu

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;
    }
}

Konstruktor yang lebih pendek

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 */
}

Pada titik ini saya tidak yakin apakah saya harus berurusan dengan kerugian besar di masa depan yang disebabkan oleh struktur ini. Apakah ini akan menjadi cara yang dapat diterima untuk mengurangi jumlah definisi DI?

bukart
sumber

Jawaban:

7

Lihat \Magento\Framework\Model\Context, dirujuk dalam contoh Anda. Apa yang Anda jelaskan persis seperti apa fungsinya. Magento menggunakan Contextobjek serupa di seluruh inti untuk mempersingkat daftar DI.

Satu-satunya hal yang perlu diingat adalah bahwa ini tidak boleh digunakan untuk menyembunyikan keputusan arsitektur yang buruk . Anda harus mempertimbangkan apakah setiap kelas yang Anda butuhkan 'seluruh modul Anda' benar-benar diperlukan, dan jika demikian, apakah ada cara alternatif untuk mengatur kode Anda yang akan mencapai tujuan yang sama dengan lebih baik. Sangat mudah untuk memperkenalkan masalah kinerja yang tidak disengaja.

Ryan Hoerr
sumber
baik ya ... itu tidak bisa digunakan untuk "menyembunyikan keputusan arsitektur yang buruk" poin terbesar saya adalah jumlah pembantu yang harus saya gunakan (saya sendiri dan pembantu inti) kelas-kelas Konteks bagi saya tampaknya melakukan apa yang Anda katakan, Saya hanya tidak yakin. thx 4 saran
bukart
Jadi dalam istilah awam, ContextKelas adalah kelas Magento yang mencakup seluruh bagian Magento? yaitu Konteks Kategori, akan membantu mengelola Tambah / Edit / Hapus / Lihat Kategori tanpa perlu mengimpor beberapa kelas untuk melakukan tindakan yang sama?
MackieeE
@ MackieeE Tidak, tidak cukup. Mereka mencakup beberapa dependensi Magento untuk kelas yang Anda lihat. Mereka biasanya agak abstrak / jauh rantai pewarisan, tidak spesifik untuk kelas akhir tertentu (seperti Kategori). Jika Anda melihat \Magento\Catalog\Model\Category, Anda akan melihat bahwa itu termasuk yang sama yang \Magento\Framework\Model\Contextsaya sebutkan - sebenarnya tidak ada di sana tentang kategori sama sekali. Anda sedang mencari repositori - lihatlah \Magento\Catalog\Api\CategoryRepositoryInterface.
Ryan Hoerr
4

Saya cukup yakin Anda bukan satu-satunya dalam kasus ini dan dalam beberapa hal saya benar-benar mengerti mengapa Anda berpikir untuk melakukan ini.

Bagi saya, masalah utama yang saya lihat dengan pendekatan seperti itu adalah Anda kehilangan salah satu manfaat utama Injeksi Ketergantungan yang adalah untuk mengetahui langsung apa yang tergantung pada kelas Anda saat memeriksa konstruktor.

Manfaat penting lain dari Dependency Injection adalah membuat kode lebih mudah untuk diuji dalam kerangka kerja otomatis. Dalam kasus Anda itu pasti satu kelemahan.

Itulah dua alasan yang muncul tetapi mungkin ada lebih banyak.

EDIT: Saya hanya akan menambahkan kutipan dari Alan Kent (yang merupakan bagian dari Magento) yang dapat Anda temukan di komentar dari pertanyaan ini :

Saya biasanya tidak menyarankan metode melempar ke kelas pembantu yang tidak terkait. Lebih baik memiliki kelas terpisah yang mewakili tujuan nyata. Atau gunakan metode statis dalam hal ini tidak perlu konstruktor (kode panggilan bertanggung jawab untuk menangani struktur data yang diperlukan).

Raphael di Digital Pianism
sumber
Padahal saya sepenuh hati menyetujui alasan di atas. Namun sebagai pemula Magento sendiri - sepertinya ada kurva belajar yang besar untuk mempelajari kelas mana yang diperlukan dan bergantung satu sama lain sebelum Anda dapat mulai berkembang.
MackieeE