Jika SOLID adalah seperangkat prinsip untuk menulis kode kualitas, maka Law of Demeter (LoD) dan Tell Don't Ask (TDA) adalah trik khusus untuk mencapai SOLID.
Hari ini kita akan berbicara tentang Hukum Demeter ("Hukum Demeter").
Berlebihan
Prinsip ini membantu untuk menentukan: "Bagaimana saya mendapatkan / memodifikasi objek bersarang" - berlaku dalam bahasa di mana Anda dapat mendefinisikan "kelas" dengan properti dan metode.
Situasi sering muncul ketika kita dari suatu tempat (misalnya, dari permintaan HTTP) mendapatkan id dari entitas ʻa`, mengikutinya ke database dan dari entitas ʻa` kita perlu mendapatkan / mengubah entitas `b` dengan memanggil metode` Metode`.
Jadi Wikipedia mengatakan:
Kode `abMethod ()` melanggar Hukum Demeter, dan kode `a.Method ()` benar.
Contoh
Pengguna memiliki Posting yang memiliki Komentar. Anda ingin menerima "Komentar Posting Terakhir".
Anda dapat mengajukan ini:
const posts = user.posts
const lastPostComments = posts[posts.length-1].comments
Atau seperti ini:
const userLastPostComments = user.getPosts().getLast().getComments()
Masalah: kode mengetahui tentang seluruh hierarki data bersarang dan jika hierarki ini berubah / meluas, di mana pun rantai ini dipanggil, Anda harus membuat perubahan (refactor the code + tes).
Untuk mengatasi masalah tersebut, terapkan LoD:
const userLastPostComments = user.getLastPostComments()
Tapi sudah di ` User` kita menulis:
class User {
// ...
getLastPostComments(): Comments {
return this.posts.getLastComments()
}
// ...
}
Cerita yang sama dengan komentar ditambahkan. Kami dari:
const newComment = new Comment(req.body.postid, req.body.content)
user.getPosts().addComment(newComment)
Atau, jika Anda ingin memamerkan diagnosis Anda:
const newComment = new Comment(req.body.postid, req.body.content)
const posts = user.posts
posts[posts.length-1].comments.push(newComment)
Mengubah ini menjadi ini:
const posts = user.addCommentToPost(req.body.postid, req.body.content)
Dan untuk ` Pengguna` :
class User {
// ...
addCommentToPost(postId: string, content: string): void {
// The cleanest
const post = this.posts.getById(postId)
return post.addComment(content)
}
// ...
}
Klarifikasi: ` new Comment` dapat dibuat di luar` user` atau ` post` , semuanya tergantung pada bagaimana logika aplikasi Anda diatur, tetapi semakin dekat dengan pemilik entitas (dalam hal ini,` post` ), semakin baik.
Apa fungsinya?
Kami menyembunyikan detail implementasi, dan jika ada perubahan / ekstensi hierarki (misalnya, posisi tidak hanya akan terletak di `properti posts ') Anda hanya perlu memfaktor ulang metode` getLastPostComments` / ` addCommentToPost` dan menulis ulang pengujian unit hanya untuk metode ini.
Apa kekurangannya
Banyak tambahan kode.
Dalam project kecil, sebagian besar metode hanya akan menjadi ` getter` /` setter` .
Kapan digunakan
(1) LoD cocok untuk Model, Entitas, Agregat, atau Kelas yang memiliki koneksi dalam / kompleks / gabungan.
(2) Kode memerlukan konsep: "Dapatkan komentar dari posting terakhir" - dan posting Anda tidak ada di properti pertama, tetapi di 2 atau lebih, maka, yang pasti, Anda perlu membuat metode ` getLastPostComments` dan menggabungkan beberapa properti dengan properti berbeda posting.
(3) Saya mencoba menggunakan prinsip ini sesering mungkin dalam hal mengubah (mengubah, membuat, menghapus) data. Dan lebih jarang dalam hal mengambil data.
(4) Berdasarkan akal sehat.
Retas hidup
Banyak yang mulai mengkhawatirkan jumlah metode proxy, jadi inilah penyederhanaannya:
Agar tidak membuat metode proxy dalam jumlah tak terbatas, LoD dapat digunakan di kelas tingkat atas (dalam kasus kami, ʻUser`), dan di dalam implementasinya, ini sudah melanggar hukum. Misalnya:
const userLastPostComments = user.getLastPostComments()
class User {
// ...
getLastPostComments(): Comments {
// LoD, Post
const lastPost = this.posts[this.posts.length-1]
return lastPost.comments
}
// ...
}
Seiring waktu, jika `post` bertambah, akan memungkinkan untuk membuatnya menjadi` getLast ()` atau` getLastComments () `dan ini tidak akan memerlukan banyak refactoring.
Apa yang dibutuhkan untuk ini
LoD berfungsi dengan baik jika Anda memiliki hierarki / pohon dependensi entitas yang tepat .
Apa yang harus dibaca
(1) https://qna.habr.com/q/44822
Pastikan untuk membaca semua komentar dan komentar di komentar (sebelum komentar Vyacheslav GolovanovSLY_G), mengingat bahwa ada contoh benar dan salah
(2) https://ru.wikipedia.org/wiki/Demeter_Law
(3) Artikel
PS
Saya bisa mengacaukan beberapa detail / contoh atau menjelaskannya tidak cukup jelas, jadi tulis di komentar yang Anda perhatikan, saya akan membuat perubahan. Semuanya bagus.
PPS
Baca baris komentar ini , di dalamnya kitasarang kami menganalisis kasus yang tidak sepenuhnya menyala secara lebih rinci di artikel ini