Menjelajahi beberapa kode yang saya tulis, saya menemukan konstruksi berikut yang membuat saya berpikir. Sekilas, sepertinya cukup bersih. Ya, dalam kode aktual getLocation()
metode ini memiliki nama yang sedikit lebih spesifik yang lebih baik menggambarkan dengan tepat lokasi yang didapatnya.
service.setLocation(this.configuration.getLocation().toString());
Dalam hal ini, service
adalah variabel instan dari tipe yang dikenal, dideklarasikan dalam metode. this.configuration
berasal dari diteruskan ke konstruktor kelas, dan merupakan turunan dari kelas yang mengimplementasikan antarmuka spesifik (yang mengamanatkan getLocation()
metode publik ). Oleh karena itu, tipe kembalinya ekspresi this.configuration.getLocation()
diketahui; khusus dalam hal ini, itu adalah java.net.URL
, sedangkan service.setLocation()
menginginkan a String
. Karena dua jenis String dan URL tidak langsung kompatibel, beberapa jenis konversi diperlukan agar pas dengan pasak persegi di lubang bundar.
Namun , menurut Hukum Demeter seperti dikutip dalam Kode Bersih , metode f di kelas C seharusnya hanya memanggil metode pada C , benda yang dibuat oleh atau lulus sebagai argumen untuk f , dan benda diadakan di variabel misalnya dari C . Apa pun di luar itu (final toString()
dalam kasus khusus saya di atas, kecuali jika Anda mempertimbangkan objek sementara yang dibuat sebagai hasil dari pemanggilan metode itu sendiri, di mana seluruh UU tampaknya diperdebatkan) dilarang.
Adakah alasan yang masuk akal mengapa panggilan seperti di atas, mengingat kendala yang ada, harus dihilangkan atau bahkan dilarang? Atau apakah saya hanya menjadi terlalu rewel?
Jika saya harus menerapkan metode URLToString()
yang hanya panggilan toString()
pada URL
objek (seperti yang dikembalikan oleh getLocation()
) berlalu untuk itu sebagai parameter, dan kembali hasilnya, saya bisa membungkus getLocation()
panggilan di dalamnya untuk mencapai hasil yang sama persis; efektif, saya hanya akan memindahkan konversi satu langkah ke luar. Apakah itu entah bagaimana membuatnya diterima? ( Tampaknya bagi saya, secara intuitif, bahwa seharusnya tidak membuat perbedaan apa pun, karena semua yang dilakukan adalah menggerakkan sedikit hal. Namun, menurut surat Hukum Demeter yang dikutip, itu akan dapat diterima, karena saya kemudian akan beroperasi secara langsung pada parameter ke suatu fungsi.)
Apakah ada bedanya jika ini tentang sesuatu yang sedikit lebih eksotis daripada memanggil toString()
tipe standar?
Saat menjawab, perlu diingat bahwa mengubah perilaku atau API dari tipe service
variabel tidak praktis. Juga, demi argumen, katakanlah bahwa mengubah tipe kembalinya getLocation()
juga tidak praktis.
sumber
Hukum Demeter adalah pedoman desain, bukan hukum yang harus diikuti secara agama.
Jika Anda merasa bahwa kelas Anda cukup terpisah daripada tidak ada yang salah dengan garis
this.configuration.getLocation()
terutama jika, seperti yang Anda katakan, tidak praktis untuk mengubah bagian lain dari API.Saya cukup yakin bahwa klien akan sangat bahagia bahkan jika Anda membuat Hukum Demeter berkeping-keping, selama Anda memberikan apa yang dia inginkan dan tepat waktu. Yang bukan alasan untuk membuat perangkat lunak yang buruk, tetapi pengingat untuk bersikap pragmatis saat mengembangkan perangkat lunak.
sumber
this.configuration
merupakan variabel instan dari jenis antarmuka yang dikenal, memanggil metode di atasnya yang didefinisikan oleh antarmuka itu tampaknya baik-baik saja bahkan menurut interpretasi yang ketat. Ya, saya tahu itu adalah pedoman, seperti KISS, SOLID, YAGNI, dan sebagainya. Ada sangat sedikit jika memang ada "hukum" (dalam arti hukum) dalam pengembangan perangkat lunak umum.Satu-satunya hal yang dapat saya pikirkan untuk tidak menulis kode seperti ini adalah bagaimana jika
this.configuration.getLocation()
mengembalikan null? Itu tergantung pada kode Anda di sekitarnya dan audiens target menggunakan kode ini. Tetapi seperti yang dikatakan Marco - hukum Demeter adalah aturan praktis - itu baik untuk diikuti, tetapi jangan mematahkan punggung Anda dengan melakukan hal yang tidak perlu.sumber
this.configuration.getLocation()
akan mengembalikan nol, maka kita (a) kemungkinan besar tidak akan pernah sejauh itu, atau (b) sesuatu yang sangat buruk telah terjadi untuk sementara, dalam hal ini saya ingin kode gagal. Jadi sementara ini jelas merupakan poin yang valid secara umum, dalam kasus khusus ini cukup aman untuk mengatakan bahwa itu tidak berlaku. Juga, mengatasi semua ini dan banyak lagi adalah handler pengecualian yang dirancang khusus untuk menghadapi kegagalan yang tak terduga.Mengikuti Hukum Demeter dengan ketat berarti Anda harus mengimplementasikan metode dalam objek konfigurasi seperti:
tetapi secara pribadi saya tidak akan repot karena ini adalah situasi kecil, dan lagi pula tangan Anda agak terikat karena API Anda tidak dapat berubah. Aturan pemrograman adalah tentang apa yang harus Anda lakukan ketika Anda punya pilihan, tetapi kadang-kadang Anda tidak punya pilihan.
sumber