如果SOLID是用于编写质量代码的一组原则,则Demeter法则(LoD)和告诉不要问(TDA)是实现SOLID的特定技巧。
今天我们将讨论迪特耳特法则(“迪特尔法则”)。
夸张的
该原则有助于确定:“我将如何获取/修改嵌套对象”-适用于可以用属性和方法定义“类”的语言。
通常,当我们从某个地方(例如从HTTP请求)接收到实体``a''的ID,然后将其跟随到数据库中时,通常需要一种情况,即我们需要通过调用方法``方法''从实体`a`获取/更改实体``b''。
因此,维基百科说:
`abMethod()`代码违反了Demeter定律,并且`a.Method()`代码正确。
例
用户具有评论的帖子。您想收到“最新评论”。
您可以提交以下文件:
const posts = user.posts
const lastPostComments = posts[posts.length-1].comments
或像这样:
const userLastPostComments = user.getPosts().getLast().getComments()
问题:代码了解嵌套数据的整个层次结构,并且如果此层次结构发生更改/扩展,则无论在何处调用此链,都必须进行更改(重构代码+测试)。
要解决此问题,请应用LoD:
const userLastPostComments = user.getLastPostComments()
但是已经在` User`中写了:
class User {
// ...
getLastPostComments(): Comments {
return this.posts.getLastComments()
}
// ...
}
同样的故事,加上评论。我们是从:
const newComment = new Comment(req.body.postid, req.body.content)
user.getPosts().addComment(newComment)
或者,如果您想炫耀您的诊断:
const newComment = new Comment(req.body.postid, req.body.content)
const posts = user.posts
posts[posts.length-1].comments.push(newComment)
变成这个:
const posts = user.addCommentToPost(req.body.postid, req.body.content)
对于` User`:
class User {
// ...
addCommentToPost(postId: string, content: string): void {
// The cleanest
const post = this.posts.getById(postId)
return post.addComment(content)
}
// ...
}
澄清:可以在用户或帖子之外创建新评论,这完全取决于应用程序逻辑的排列方式,但是越接近实体所有者(在这种情况下,就是帖子)就越好。
它有什么作用?
我们隐藏了实现细节,并且如果有更改/层次结构扩展(例如,职位将不仅位于``职位的属性''中),您只需重构方法getLastPostComments` /` addCommentToPost`并重写单元测试仅此方法。
有什么缺点
很多额外的 码。
在小型项目中,大多数方法只是` getter` /` setter`。
何时使用
(1)LoD适用于具有深/复杂/合并连接的模型,实体,集合或类。
(2)代码需要这样的概念:“获取最后一篇文章的评论”-并且您的文章不在1st属性中,而是在2个或更多属性中,那么,您当然需要制作` getLastPostComments`方法并合并具有不同属性的多个属性帖子。
(3)在转换(更改,创建,删除)数据时,我尝试尽可能多地使用此原理。检索数据的频率也降低了。
(4)基于常识。
生活骇客
许多人开始担心代理方法的数量,因此有一个简化:
为了不创建无限数量的代理方法,可以在顶级类(在我们的例子中为User)中使用LoD,并且在实现中已经违反了法律。例如:
const userLastPostComments = user.getLastPostComments()
class User {
// ...
getLastPostComments(): Comments {
// LoD, Post
const lastPost = this.posts[this.posts.length-1]
return lastPost.comments
}
// ...
}
随着时间的流逝,如果`post`增长了,有可能使它成为`getLast()`或`getLastComments()`的方法,而这将不需要很多重构。
为此需要什么
如果您具有适当的实体依赖关系树/层次结构,则LoD效果很好。
读什么
(1)https://qna.habr.com/q/44822
确保阅读所有评论和评论(在评论Vyacheslav Golovanov之前SLY_G),请记住同时存在正确和错误的示例
(2)https://ru.wikipedia.org/wiki/Zakon_Demeter
(3)文章
聚苯乙烯
我可能会搞砸一些细节/示例,或者解释得不够清楚,因此请在您注意到的评论中写下来,然后进行更改。都好。
PPS
阅读这行评论,在其中巢穴 我们将在本文中更详细地分解一个未完全点亮的盒子