Sihir getter pada Varien_Object
(M1) dan DataObject
(M2) adalah praktik umum, tetapi dengan Magento 2 rasanya salah menggunakannya.
Baik:
- mudah dibaca / ditulis
Buruk
- Ini menyebabkan masalah saat menggunakan angka dalam kunci (lihat: Magento 2: cara berbeda mendapatkan bidang koleksi atau Dapatkan atribut Produk Kustom menggunakan kasing unta )
- alat analisis kode mengeluh tentang metode yang tidak ada
Pertanyaan
Dengan Magento 2 kami memiliki dua metode baru:
getDataByKey($key)
getDataByPath($path)
Apakah ada alasan bagus untuk tetap menggunakan getData($key)
atau mendapatkan sihir?
Edit:
@Vinai terima kasih. Saya tidak menyebutkan @method
metodenya, karena pendekatan saya sangat berbeda.
Ini hanya membantu IDE, tetapi tidak berdampak pada hal-hal lain.
Ada beberapa PR gabungan yang merupakan "optimasi mikro" seperti casting untuk (int)
bukannya intval()
atau mendapatkan ukuran array di luar loop (bahkan untuk array kecil).
Di sisi lain ada
getter ajaib, yang memiliki "overhead" seperti yang dijelaskan Marius ....
strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
getData($key)
mehtods juga harus 2-3 pemeriksaan tambahan ...if ('' === $key) {
if (strpos($key, '/')) {
if ($index !== null) {
Untuk kode sendiri, sepenuhnya setuju untuk memilih metode nyata, tetapi dalam kasus yang sama tidak mungkin ... misalnya Anda telah membuat acara khusus ...
$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');
Menggunakan ke-3 dengan yang /** @var some $value */
terbaik bagi saya. (?)
Jawaban:
Pertanyaan di atas adalah tentang menggunakan metode sihir vs.
getDataByKey
ataugetDataByPath
. Saya pikir ada opsi ketiga juga, dan itu menerapkan metode pengambil dan penyetel nyata.Semua
getData*
metode memiliki kelemahan yang harus dicatat untuk inferensi tipe agar berfungsi.Biasanya itu dilakukan dengan
/* @var string $foo */
anotasi di atasgetData*
panggilan.Ini agak bau, karena jenis data harus dideklarasikan di kelas yang berisi data, bukan kelas yang memanggil
getData*
.Alasan untuk itu adalah bahwa jika data berubah, kelas adalah yang paling mungkin diperbarui, tidak semua
getData*
situs panggilan.Itu sebabnya saya pikir metode nyata meningkatkan rawatan dibandingkan dengan menggunakan
getData*
accessors.Jadi saya pikir itu bermuara pada trade off antara pemeliharaan dan implementasi yang lebih cepat (lebih sedikit kode untuk ditulis).
Untungnya, saat ini IDE benar-benar pandai menciptakan implementasi pengambil dan penyetel bagi kami, sehingga argumen tersebut tidak benar-benar berlaku lagi.
Satu lagi argumen menentang pengambil getar dan setter ajaib yang hilang dari pertanyaan di atas adalah bahwa tidak mungkin membuat plugin untuk mereka.
Satu-satunya nilai lain yang saya pikir dapat saya tambahkan ke topik adalah mencoba mengumpulkan alasan untuk menggunakan atau tidak menggunakan
@method
anotasi, jika menerapkan metode nyata tidak mungkin karena beberapa alasan.Pro
@method
penjelasan adalah kode kurang sedikit untuk menulis dibandingkan dengan menerapkan getter nyata dan setter. Ini hampir tidak benar meskipun saat ini karena IDE pandai menghasilkan metode accessor, jadi itu bukan manfaat nyata lagi.Cons
@method
anotasi dan metode nyata dengan nama yang sama, tanda tangan jenis anotasi menimpa metode nyata selama analisis kode statis, yang merupakan kebalikan dari apa yang dilakukan penerjemah PHP. Ini lagi dapat dengan mudah menyebabkan bug halus.Untuk alasan di atas, saya pribadi tidak menggunakan
@method
anotasi jika saya dapat menghindarinya.Untuk kode yang dimaksudkan untuk hidup lama saya menerapkan metode getter dan setter nyata. Keuntungan rawatan sebanding dengan upaya memicu IDE untuk menghasilkannya.
Untuk kode eksperimental yang lebih banyak selama spike, atau untuk detail implementasi sederhana dari sebuah modul, saya menggunakan
getData*
metode juga, karena saya malas.sumber
Ya itu bau, tetapi bisakah (dan harus?) Dihindari. Saya pikir ini adalah kode yang sangat umum dan sering disarankan:
Masalahnya adalah Anda hanya menebak bahwa nilai kembali adalah tipe
Foo
dengangetId()
metode callable .Untuk pemeliharaan, mengapa tidak menganggap jenis variabel dan menambahkan
InvalidArgumentException
?Ini juga memperbaiki analisis kode statis jika
$model->getProduct()
memiliki tipe pengembalian yang berbeda - sepertiFoo|false
. Dalam kasus pertama itu akan mengeluh tentang memanggildoSomething()
yang mungkinfalse
.sumber