The Law of Demeter menyatakan berikut ini:
- Setiap unit harus memiliki pengetahuan yang terbatas tentang unit lain: hanya unit "erat" yang terkait dengan unit saat ini.
- Setiap unit hanya boleh berbicara dengan teman-temannya; jangan berbicara dengan orang asing.
- Hanya berbicara dengan teman dekat Anda.
C # 6.0 memperkenalkan operator baru yang disebut operator null-kondisional . IMHO, itu membuat pengkodean lebih mudah dan meningkatkan keterbacaan. Tetapi juga membuatnya lebih mudah untuk menulis lebih banyak kode yang digabungkan, karena lebih mudah untuk menavigasi melalui bidang kelas, sudah memeriksa nullity (sesuatu seperti var x = A?.B?.C?.D?.E?.F?
).
Apakah benar menyatakan bahwa operator baru ini bertentangan dengan Hukum Demeter?
c#
design-patterns
object-oriented-design
Arthur Rizzo
sumber
sumber
A?.B?.C?.D?.E?.F?
akan melanggarnya - LoD bukan tentang berapa banyak titik dan jika metode panggilan memiliki informasi tentang struktur yang tidak melanggar poinnya, panggilan semacam itu akan dapat diterima dengan sempurna. Bahwa kode tersebut bisa melanggar LOD tidak cukup untuk mengatakan bahwa semua penggunaan itu melakukan melanggar LOD.X.Y.Z.W.U
merupakan pelanggaran terhadap "hukum". Tapi, dalam pengalaman saya berurusan dengan kode, 90% dari waktu itu hanya kode digabungkan jelek..?
ada lagi pelanggaran LoD daripada+
atau-
tidak.Jawaban:
Tidak *
* Operator bersyarat nol adalah alat dalam bahasa dan kerangka kerja NET. Setiap alat memiliki kemampuan untuk disalahgunakan dan digunakan dengan cara yang dapat membahayakan maintainability aplikasi tertentu.
Tapi fakta bahwa alat dapat menjadi disalahgunakan tidak berarti bahwa itu memiliki untuk disalahgunakan, atau bahwa alat ini melanggar prinsip tertentu (s) yang mungkin diadakan.
Hukum Demeter dan lainnya adalah pedoman tentang bagaimana Anda harus menulis kode Anda. Itu ditargetkan untuk manusia, bukan alat. Jadi fakta bahwa bahasa C # 6.0 memiliki alat baru di dalamnya tidak mempengaruhi bagaimana Anda seharusnya menulis dan menyusun kode Anda.
Dengan alat baru, Anda perlu mengevaluasi sebagai ... jika orang yang berakhir menjaga kode Anda akan menjadi psikopat ... . Perhatikan lagi, bahwa ini adalah panduan untuk orang yang menulis kode dan bukan tentang alat yang digunakan.
sumber
foo = new FiveDMatrix(); foo.get(0).get(0).get(0).get(0).set(0,1);
akan baik-baik saja (dan tidak lebih buruk darifoo[0][0][0][0][0] = 1
) ... dan banyak situasi lain di mana seperti itu tidak melanggar LoD.Dom file = prase("some.xml"); file.get(tag1).getChild().get(tag2).getChild() ...
adalah masalah pemrosesan struktur kode bodoh. Ini bukan orang asing ... hanya bodoh. Itu.?
menjadi sangat berguna dalam struktur seperti itu.Semacam.
Jika Anda hanya melakukan satu akses (
a?.Foo
) maka itu setara dengan:yang disetujui kebanyakan orang bukanlah pelanggaran terhadap Hukum Demeter. Pada titik itu, itu hanya gula sintaksis untuk meningkatkan keterbacaan.
Lebih dari itu, dan itu mungkin akan melanggar Hukum Demeter, dan fitur ini cenderung mempromosikan penggunaan semacam itu. Saya bahkan akan mengatakan bahwa penggunaan "baik" di atas saja tidak cukup untuk menjamin perubahan semacam ini ke bahasa, jadi saya berharap bahwa itu dibuat untuk mendukung penggunaan yang kurang jelas baik.
Yang mengatakan, perlu diingat bahwa Hukum Demeter bukan hukum semata, tetapi lebih sebagai pedoman. Banyak kode yang melanggarnya dan berfungsi dengan baik. Kadang-kadang kesederhanaan desain atau kode bernilai lebih dari risiko yang ditimbulkan dengan melanggar Hukum Demeter.
sumber
a?.Func1(x)?.Func2(y)
Operator penggabungan nol adalah sesuatu yang lain.Tidak. Mari kita pertimbangkan operatornya sendiri, dan penggunaan berantai yang Anda miliki untuk itu.
Sendiri
.?A
tergantung pada jumlah pengetahuan yang sama dari kelas nilai-kiri dan jenis yang dikembalikan oleh metode seperti.A != null
halnya, yaitu. Perlu diketahui bahwaA
properti itu ada dan mengembalikan nilai yang dapat dibandingkannull
.Kita hanya bisa berargumen bahwa ini melanggar hukum Demeter jika properti yang diketik memang demikian. Kami bahkan tidak dipaksa untuk memiliki
A
jenis beton (nilainya dapat berupa jenis turunan). Kopling di sini minimal.Sekarang mari kita pertimbangkan
var x = A?.B?.C?.D?.E?.F
.Yang berarti bahwa
A
harus dari jenis yang bisa nol, atau bisa memilikiB
properti, yang harus dari jenis yang bisa nol atau memilikiC
properti, dan seterusnya sampai jenisE
properti menjadi sesuatu yang bisa nol atau bisa memilikiF
properti.Dengan kata lain, kita perlu melakukan ini dengan bahasa yang diketik secara statis atau menerapkan batasan pada jenis yang dapat dikembalikan jika pengetikan longgar. C # dalam kebanyakan kasus menggunakan pengetikan statis, jadi kami tidak mengubah apa pun.
Jika kami punya maka kode berikut juga akan melanggar hukum:
Yang persis sama . Kode ini yang menggunakan kopling elemen yang berbeda perlu "tahu" tentang rantai penuh kopling, tetapi menggunakan kode yang tidak melanggar Hukum Demeter untuk melakukannya, dengan setiap unit memiliki kopling yang terdefinisi dengan baik dengan selanjutnya.
sumber
var x = A?.B?.C?.D?.E?.F
daripada semua jika / elses meskipun pada akhirnya mereka sama.A?.B?.C?.D?.E?.F
karena ada sedikit yang bisa salah; entah kita harus mencobaF
melalui jalur itu, atau kita tidak seharusnya, sementara bentuk yang lebih panjang bisa memiliki kesalahan di dalamnya serta kesalahan itu tidak menjadi hal yang benar untuk dilakukan.A.B.C.D
. Jauh lebih sederhana untuk memiliki satu hal yang harus diwaspadai (akses properti dirantai) daripada dua hal berbeda yang bergantung pada detail yang sangat tidak relevan (pengecekan nol)Objek dapat dibuat untuk tujuan merangkum perilaku atau menyimpan data, dan objek dapat dibuat untuk tujuan dibagikan dengan kode luar atau dipegang secara pribadi oleh penciptanya.
Objek yang dibuat untuk tujuan perilaku enkapsulasi (apakah dibagikan atau tidak), atau untuk yang dibagikan dengan kode luar (apakah mereka merangkum perilaku atau data) umumnya harus diakses melalui antarmuka permukaan mereka. Namun, ketika benda-benda yang menyimpan data dibuat untuk digunakan secara eksklusif oleh penciptanya, alasan Hukum-Demeter normal untuk menghindari akses "dalam" tidak berlaku. Jika bagian dari kelas yang menyimpan atau memanipulasi data dalam objek diubah dengan cara yang memerlukan penyesuaian kode lain, akan mungkin untuk menjamin bahwa semua kode tersebut akan diperbarui karena - seperti disebutkan di atas - objek dibuat untuk penggunaan eksklusif satu kelas.
Sementara aku memikirkannya? Operator mungkin bisa dirancang lebih baik, ada situasi yang cukup di mana objek menggunakan struktur data bersarang sehingga operator memiliki banyak kasus penggunaan yang tidak akan melanggar prinsip-prinsip yang dinyatakan oleh Hukum Demeter. Fakta bahwa itu dapat digunakan untuk melanggar LoD tidak boleh dianggap sebagai argumen terhadap operator, karena itu tidak lebih buruk daripada "." operator dalam hal itu.
sumber