Se SOLID é um conjunto de princípios para escrever código de qualidade, então a Lei de Demeter (LoD) e Diga, Não Pergunte (TDA) são truques específicos para alcançar SOLID.
Hoje vamos falar sobre a Lei de Deméter ("Lei de Deméter").
Exagerado
Este princípio ajuda a determinar: "Como irei obter / modificar objetos aninhados" - aplicável em linguagens onde você pode definir "classes" com propriedades e métodos.
Freqüentemente, há uma situação em que de algum lugar (por exemplo, de uma solicitação HTTP) recebemos o id da entidade `a`, seguimos para o banco de dados e da entidade` a` precisamos obter / alterar a entidade` b` chamando o método` Método`.
Então a Wikipedia diz:
O código `abMethod ()` viola a Lei de Demeter, e o código `a.Method ()` está correto.
Exemplo
O usuário tem postagens com comentários. Você deseja receber "Comentários da última postagem".
Você pode registrar isto:
const posts = user.posts
const lastPostComments = posts[posts.length-1].comments
Ou assim:
const userLastPostComments = user.getPosts().getLast().getComments()
Problema: o código conhece toda a hierarquia de dados aninhados, e se esta hierarquia muda / se expande, onde quer que esta cadeia seja chamada, você terá que fazer mudanças (refatorar o código + testes).
Para resolver o problema, aplique o LoD:
const userLastPostComments = user.getLastPostComments()
Mas já em ` User` escrevemos:
class User {
// ...
getLastPostComments(): Comments {
return this.posts.getLastComments()
}
// ...
}
A mesma história com a adição de um comentário. Nós somos de:
const newComment = new Comment(req.body.postid, req.body.content)
user.getPosts().addComment(newComment)
Ou, se você quiser mostrar seu diagnóstico:
const newComment = new Comment(req.body.postid, req.body.content)
const posts = user.posts
posts[posts.length-1].comments.push(newComment)
Transformando isso em:
const posts = user.addCommentToPost(req.body.postid, req.body.content)
E para ` User` :
class User {
// ...
addCommentToPost(postId: string, content: string): void {
// The cleanest
const post = this.posts.getById(postId)
return post.addComment(content)
}
// ...
}
Esclarecimento: ` new Comment` pode ser criado fora de` user` ou ` post` , tudo depende de como a lógica de sua aplicação está organizada, mas quanto mais próximo do dono da entidade (neste caso,` post` ), melhor.
O que isso faz?
Escondemos os detalhes de implementação, e se houver uma extensão de mudança / hierarquia (por exemplo, as posições não ficarão apenas na `propriedade das postagens '), você só precisa refatorar o método` getLastPostComments` / ` addCommentToPost` e reescrever o teste de unidade apenas este método.
Quais são os contras
Muito extra código.
Em projetos pequenos, a maioria dos métodos será apenas ` getter` /` setter` .
Quando usar
(1) LoD é bom para modelos, entidades, agregados ou classes que têm conexões profundas / complexas / mescladas.
(2) O código requer o conceito: "Pegue os comentários da última postagem" - e suas postagens não estão na 1ª propriedade, mas em 2 ou mais, então, com certeza, você precisa fazer o método ` getLastPostComments` e mesclar várias propriedades com diferentes Postagens.
(3) Tento usar esse princípio tão frequentemente quanto possível quando se trata de transformar (alterar, criar, excluir) dados. E com menos frequência quando se trata de receber dados.
(4) Com base no bom senso.
Hack da vida
Muitos começaram a se preocupar com o número de métodos de proxy, então aqui está uma simplificação:
para não criar um número infinito de métodos de proxy, LoD pode ser usado na classe de nível superior (no nosso caso, ʻUser`), e dentro da implementação já está infringindo a lei. Por exemplo:
const userLastPostComments = user.getLastPostComments()
class User {
// ...
getLastPostComments(): Comments {
// LoD, Post
const lastPost = this.posts[this.posts.length-1]
return lastPost.comments
}
// ...
}
Com o tempo, se o `post` crescer, será possível torná-lo métodos` getLast () ʻou` getLastComments ()` e isso não implicará em muita refatoração.
O que é necessário para isso
O LoD funciona bem se você tiver uma árvore / hierarquia de dependência de entidade adequada .
O que ler
(1) https://qna.habr.com/q/44822
Certifique-se de ler todos os comentários e comentários de comentários (antes do comentário Vyacheslav GolovanovSLY_G), lembrando que existem exemplos corretos e incorretos
(2) https://ru.wikipedia.org/wiki/Demeter_Law
(3) Artigo
PS
Eu poderia estragar alguns detalhes / exemplos ou explicar que não está claro o suficiente, então escreva nos comentários que você notou, eu farei alterações. Tudo bom.
PPS
Leia esta linha de comentários , nela nóscovil analisamos um caso incompletamente iluminado em mais detalhes neste artigo