Saya refactoring aplikasi PHP , dan saya coba lakukan memiliki injeksi ketergantungan (DI) sebanyak mungkin.
Saya merasa memiliki pemahaman yang baik tentang cara kerjanya, dan tentu saja saya bisa melihat kelas saya menjadi jauh lebih ramping dan lebih kuat.
Saya refactoring sehingga saya dapat menyuntikkan ketergantungan daripada membuat objek baru di dalam kelas, tetapi pada titik tertentu saya harus membuat beberapa objek, yaitu, menggunakan new
kata kunci yang ditakuti .
Masalah yang saya hadapi sekarang adalah pada titik mana saya bisa benar-benar membuat objek baru? Sepertinya saya akan berakhir di kelas tingkat atas, membuat banyak objek baru karena tidak ada tempat lain untuk pergi. Ini terasa salah.
Saya telah membaca beberapa blog yang menggunakan kelas pabrik untuk membuat semua objek, dan kemudian Anda menyuntikkan pabrik ke kelas lain. Anda kemudian dapat memanggil metode pabrik, dan pabrik membuat objek baru untuk Anda.
Kekhawatiran saya dengan melakukan ini adalah sekarang kelas pabrik saya akan menjadi new
gratis-untuk-semua! Saya kira ini mungkin baik-baik saja karena mereka adalah kelas pabrik, tetapi apakah ada beberapa aturan yang harus dipatuhi ketika menggunakan pola pabrik dan DI, atau apakah saya akan jauh dari sasaran di sini?
sumber
new
. Tentu saja ada beberapa titik masuk di mana Anda perlu memanggil ke wadah IoC, tetapi seharusnya tidak banyak. Biasanya Anda mengkonfigurasi IoC sekali dan kemudian meminta satu kelas untuk diselesaikan per permintaan. Dalam kasus MVC itu biasanya controller.Jawaban:
Setelah sedikit googling untuk ini, sepertinya (seperti yang disebutkan dalam komentar di atas) kelas tingkat atas yang saya bicarakan disebut Composition Root .
Tampaknya memang solusi yang diterima untuk menambahkan penciptaan semua objek dalam Komposisi Root ini (atau merujuk wadah IoC dari sini).
Kekhawatiran asli saya dengan ini adalah bahwa kelas atas ini akan berakhir sedikit berantakan. Ini benar sampai batas tertentu, tetapi kelebihan pro menimbang kontra. Sebagai contoh saya dapat melihat keterbacaan, testabilitas dan perawatan semua kelas saya yang lain telah meningkat.
Kelas tingkat atas mungkin agak berantakan, berserakan
new
danset_property()
tapi saya harus mengatakan saya sebenarnya lebih suka memiliki semua kode ini di satu tempat, daripada tersebar di seluruh kelas lainHalaman lain yang bermanfaat membahas hit kinerja dari metode ini di sini
sumber
Kelas Pabrik akan
new
ditaburkan di seluruh kelas. Itu akan menciptakan objek apa pun yang Anda minta dan mungkin dependensi objek itu. Karena pekerjaan pabrik adalah untuk instantiate objek yang benar untuk Anda milikinew
di kelas ini bukanlah hal yang buruk.DI adalah agar Anda memiliki desain yang digabungkan secara longgar. Anda dapat membuat perubahan pada aplikasi Anda dengan mengubah ketergantungan yang disediakan untuk setiap objek. Membuat aplikasi Anda fleksibel, dapat dikembangkan, dan mudah diuji.
Di tingkat atas, Anda akan memiliki kode yang akan membuat beberapa pabrik, mengatur koneksi ke layanan, dan mengirim respons. Itu akan memiliki cukup banyak
new
atau panggilan statis untuk instantiate objek yang diperlukan untuk aplikasi Anda. Di situlah tempatnya.sumber
Dua sen saya di sini:
Anda tidak menyatakan jika Anda menggunakan kerangka kerja injeksi ketergantungan. Saya pikir Anda pasti harus. Gunakan sesuatu yang memberi Anda fitur yang Anda butuhkan: /programming/9348376/guice-like-dependency-injection-frameworks-in-php .
Anda biasanya menggunakan konfigurasi atau titik pusat untuk instantiasi objek awal yang menyusun aplikasi Anda. Wadah akan membuat objek untuk Anda.
Anda kemudian mengakses objek (layanan, penyedia, pengontrol ...) melalui wadah IoC. Ini akan secara transparan membuat objek untuk Anda jika diperlukan, atau memberi Anda referensi ke instance yang ada yang sesuai.
Tentu saja, di dalam implementasi objek khusus Anda, Anda dapat membuat instance objek lain di mana Anda tidak perlu DI (struktur data, tipe kustom, dll), tapi itu pemrograman normal.
Biasanya, Anda menggunakan Pabrik jika Anda ingin kerangka kerja IoC untuk instantiate beberapa objek IoC melalui pabrik Anda (ini diperlukan saat instantiasi objek tertentu memerlukan kerja ekstra). Jika Anda bisa membuat objek dengan "Objek baru ()", dan mengatur beberapa properti, Anda tidak perlu ingin menggunakan pola Pabrik.
Dengan kata lain, saya akan mengatakan bahwa menggunakan pola Pabrik untuk kelas atau kelompok kelas tergantung pada bagaimana Anda ingin memodelkan kelas-kelas itu, bukan pada apakah Anda menggunakan DI (kecuali jika implementasi DI Anda secara eksplisit membutuhkan pabrik, yang tidak biasa).
Anda juga mengonfigurasi kerangka kerja IoC Anda untuk menggunakan Pabrik saat Anda menggunakan lib pihak ke-3 yang sudah membutuhkan penggunaan Pabrik. Dalam hal ini Anda tidak memiliki kendali tentang ini dan Anda perlu memberi tahu wadah IoC Anda: "Hei, ketika saya meminta salah satu antarmuka ini, Anda harus menggunakan pabrik ini untuk memberi saya contoh yang tepat".
Dalam hal ini, sepertinya Anda tidak perlu menggunakan pola Pabrik untuk objek / layanan / pengontrol / apa pun ini, dan Anda dapat mengkonfigurasi IoC Anda untuk membuat instance dengan "baru" kelas yang sesuai dan menyuntikkan yang lainnya.
Saya harap ini membantu.
sumber
doing DI manually beats the whole purpose of using an Inversion of Control container
- Jika maksud Anda "... yang memusatkan dependensi Anda dalam file konfigurasi" maka Anda benar, karena hanya itu yang benar-benar wadah IoC. Tujuan sebenarnya dari DI adalah decoupling, dan Anda dapat melakukannya dengan memasok dependensi Anda dalam metode konstruktor. Anda tidak perlu kerangka DI sama sekali untuk melakukan itu.