mata teras
bukan perkara yang baik untuk mengetahui terlalu banyak
sering dipanggil prinsip pengetahuan yang paling sedikit, dan peraturan yang dianjurkan oleh undang -undang Dimitese mudah difahami. Ringkasnya, katakan anda mempunyai kelas yang direka dengan baik yang melaksanakan kaedah yang diberikan, maka kaedah itu harus dihadkan untuk memanggil kaedah lain yang tergolong dalam objek berikut:Walaupun senarai itu jauh dari formal (untuk senarai lebih formal, lihat Wikipedia), perkara -perkara utama ini mudah difahami. Dalam reka bentuk tradisional, dianggap salah untuk mengetahui terlalu banyak tentang objek lain (yang secara tersirat termasuk mengetahui cara mengakses objek ketiga) kerana dalam beberapa kes objek tidak perlu pergi dari atas ke bawah yang melewati perantaraan yang kekok untuk mencari dependensi sebenar Ia perlu berfungsi seperti yang diharapkan. Ini adalah kecacatan reka bentuk yang serius untuk alasan yang jelas. Penelepon mempunyai pemahaman yang cukup luas dan terperinci tentang struktur dalaman pertengahan, walaupun ini diakses melalui beberapa getters. Selain itu, menggunakan objek pertengahan untuk mendapatkan objek yang diperlukan oleh pemanggil menggambarkan masalah itu sendiri. Lagipun, jika hasil yang sama dapat dicapai dengan secara langsung menyuntik kebergantungan, mengapa menggunakan jalan yang kompleks untuk mendapatkan kebergantungan atau memanggil salah satu kaedahnya? Proses ini tidak mempunyai makna sama sekali.
Mari kita anggap kita perlu membina modul penyimpanan fail yang menggunakan encoder polimorfik secara dalaman untuk menarik data ke dalam dan menyimpannya ke fail sasaran yang diberikan. Sekiranya kita sengaja menghubungkan modul ke pencari perkhidmatan suntikan, pelaksanaannya akan kelihatan seperti ini:
<?php namespace LibraryFile; use LibraryDependencyInjectionServiceLocatorInterface; class FileStorage { const DEFAULT_STORAGE_FILE = "data.dat"; private $locator; private $file; public function __construct(ServiceLocatorInterface $locator, $file = self::DEFAULT_STORAGE_FILE) { $this->locator = $locator; $this->setFile($file); } public function setFile($file) { if (!is_readable($file) || !is_writable($file)) { throw new InvalidArgumentException( "The target file is invalid."); } $this->file = $file; return $this; } public function write($data) { try { return file_put_contents($this->file, $this->locator->get("encoder")->encode($data), LOCK_EX); } catch (Exception $e) { throw new $e( "Error writing data to the target file: " . $e->getMessage()); } } public function read() { try { return $this->locator->get("encoder")->decode( @file_get_contents($this->file)); } catch(Exception $e) { throw new $e( "Error reading data from the target file: " . $e->getMessage()); } } }
menghilangkan beberapa butiran pelaksanaan yang tidak relevan, yang memberi tumpuan kepada pembina kelas FileStorage dan kaedah menulis () dan membaca (). Kelas ini menyuntik contoh pencari perkhidmatan yang belum ditakrifkan dan kemudiannya digunakan untuk mengambil kebergantungan (pengekod yang disebutkan di atas) untuk mengambil dan menyimpan data dalam fail sasaran. Ini biasanya melanggar undang -undang Dimitter, memandangkan kelas melintasi pencari terlebih dahulu dan kemudian mencapai encoder. Pemanggil Filestorage tahu terlalu banyak tentang struktur dalaman pencari, termasuk bagaimana untuk mengakses pengekod, yang pastinya bukan keupayaan yang saya ingin puji. Ia adalah artifak yang sememangnya berakar pada sifat pencari perkhidmatan (itulah sebabnya sesetengah orang menganggapnya sebagai anti-corak) atau mana-mana jenis pendaftaran statik atau dinamik yang lain, yang saya katakan sebelum ini. Untuk mendapatkan pemahaman yang lebih komprehensif mengenai masalah ini, mari kita periksa pelaksanaan pencari:
(Kod pencari dan pengekod ditinggalkan di sini kerana ia selaras dengan output sebelumnya. Untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
Dengan pengekod, mari kita mulakan dengan semua kelas sampel bersama -sama:
(kod sampel penggunaan ditinggalkan di sini kerana ia konsisten dengan output sebelumnya. Untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
pelanggaran undang -undang ini adalah masalah yang agak rahsia dalam kes ini dan sukar untuk mengesan dari permukaan, kecuali penggunaan mutator pencari, yang menunjukkan bahawa pada suatu ketika, pengekod entah bagaimana diambil oleh akses contoh fileStorage dan gunakan. Walau bagaimanapun, hakikat bahawa kita tahu bahawa pelanggaran itu tersembunyi di luar dunia luar bukan sahaja mendedahkan terlalu banyak maklumat mengenai struktur pencari, tetapi juga tidak perlu pasangan kelas filestorage ke pencari itu sendiri. Hanya ikuti peraturan peraturan ini dan hapuskan pencari, kami boleh mengeluarkan gandingan sambil menyediakan filestorage dengan kolaborator sebenar yang perlu dilakukan perniagaannya. Tidak ada lagi canggung, perantaraan terdedah di sepanjang jalan! Nasib baik, semua omong kosong ini dapat dengan mudah ditukar menjadi kod kerja dengan sedikit usaha. Cukup lihat versi fileStorage yang dipertingkatkan, dimitri yang dipertingkatkan di sini:
(Kod filestorage refactored ditinggalkan di sini kerana ia konsisten dengan output sebelumnya. Untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
Ini sememangnya mudah untuk refactor. Sekarang, kelas secara langsung menggunakan mana -mana pelaksana antara muka EncoderInterface, mengelakkan melintasi struktur dalaman perantaraan yang tidak perlu. Contohnya tidak dapat dinafikan, tetapi ia menggambarkan satu titik kesahihan dan menunjukkan mengapa mengikuti ajaran Undang -undang Dimitri adalah salah satu perkara terbaik yang boleh anda lakukan untuk memperbaiki reka bentuk kelas. Walau bagaimanapun, satu kes khas peraturan ini diterokai dalam buku Robert Martin "The Way of Code: Agile Software Development Manual" dan layak Analisis Khas. Sila luangkan masa untuk berfikir dengan teliti: Apa yang berlaku jika FileStorage ditakrifkan sebagai mendapatkan kolaboratornya melalui objek pemindahan data (DTO)?
(Contoh kod menggunakan DTO ditinggalkan di sini, kerana ia konsisten dengan output sebelumnya, dan untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
Ini pastinya cara yang menarik untuk melaksanakan kelas penyimpanan fail, kerana kini menggunakan DTO suntikan untuk memindahkan dan menggunakan encoder secara dalaman. Persoalan yang perlu dijawab ialah sama ada kaedah ini benar -benar melanggar undang -undang. Dari perspektif purist, ia melanggar, kerana DTO tidak diragukan lagi sebagai pertengahan yang mendedahkan seluruh strukturnya kepada pemanggil. Walau bagaimanapun, DTO hanya struktur data biasa, tidak seperti pencari perkhidmatan terdahulu, ia tidak berkelakuan sama sekali. Dan tujuan struktur data adalah ... ya, untuk mendedahkan datanya. Ini bermakna bahawa selagi pertengahan tidak melaksanakan tingkah laku (yang betul -betul bertentangan dengan tingkah laku kelas biasa, yang menyembunyikan datanya kerana ia mendedahkan tingkah laku), undang -undang dimitter tetap utuh. Coretan kod berikut menunjukkan cara menggunakan filestorage menggunakan DTO yang bermasalah:
(Contoh kod menggunakan DTO ditinggalkan di sini, kerana ia konsisten dengan output sebelumnya, dan untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
Pendekatan ini jauh lebih menyusahkan daripada melewati pengekod terus ke kelas penyimpanan fail, tetapi contohnya menunjukkan bahawa beberapa pelaksanaan rumit yang mungkin muncul pada pandangan pertama untuk menjadi pelanggaran undang -undang yang terang -terangan, biasanya agak tidak berbahaya, selagi Mereka hanya menggunakan struktur data tanpa sebarang tingkah laku tambahan.
Kesimpulan
Sebagai pelbagai heuristik yang kompleks, kadang -kadang esoterik popular di OOP, nampaknya tidak bermakna untuk menambah prinsip lain yang jelas tidak mempunyai kesan positif yang jelas terhadap reka bentuk komponen lapisan. Walau bagaimanapun, undang -undang Dimitter bukanlah satu prinsip yang tidak digunakan di dunia nyata. Walaupun nama cantiknya, Undang -undang Dimitt adalah paradigma yang kuat dengan matlamat utama untuk memudahkan pelaksanaan komponen aplikasi yang sangat dihancurkan dengan menghapuskan sebarang perantaraan yang tidak perlu. Hanya ikuti ajarannya dan tentu saja jangan dogmatik secara membabi buta dan anda akan melihat peningkatan kualiti kod. memastikan.
(bahagian Soalan Lazim ditinggalkan di sini kerana ia konsisten dengan output terdahulu. Untuk mengelakkan pertindihan, saya tidak akan mengulanginya di sini.)
Atas ialah kandungan terperinci PHP Master | Pengenalan kepada Undang -undang Demeter. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!