模式访客违反了德墨忒尔法则?

发布于 2024-12-08 21:48:05 字数 626 浏览 2 评论 0原文

德墨忒尔定律希望使类之间的耦合达到最松散的程度。

这意味着类中暴露的所有 getter/setter 中 90% 必须被“删除”并替换为“行为包含”方法。事实上,它符合“告诉,不要问”的哲学,因为客户不应该通过糟糕的 getter/setter 方法的帮助来对待行为本身。 如果在其他地方使用相同的操作,这也会减少重复的代码。

如果我们想尊重单一职责原则,这意味着具有许多行为方法的庞大类和过度使用委托。

另一方面,访问者模式定义是:

Visitor 允许您定义新操作,而无需更改其操作的元素的类。

因此,乍一看,这似乎与德米特定律的期望相反:

  • One(Visitor)意味着类结构提供 getter/setter,以便 Visitor 可以修改对象的状态而不触及类本身。

  • Other (Demeter) 鼓励将所有与对象直接相关的行为代码放在同一个类中。

所以我的问题是:

我们什么时候可以考虑关闭一个类以进行修改,从而停止在其上添加行为方法,因此更愿意将它们添加到新创建的访问者中,而客户已经使用 getter/setter 而不是行为方法的巨大风险之前在初级班就暴露过?

Law of Demeter expects to make the loosest coupling between classes.

This implies that 90% of all getters/setters exposing in class must be "deleted" and replaced by "behavior-contained" method. Indeed, it corresponds to "tell, don't ask" philosophy because client is not expected to treat behavior itself through help of poor getter/setter methods.
This reduces duplicated code also if the same action is used elsewhere.

This implies huge classes with many many behavioral methods and overuse of delegation if we want to respect Single-Responsibility principle.

On the other hand, visitor pattern definition is :

Visitor lets you define a new operation without changing the classes of the elements on which it operates.

So, at first sight, it seems to be the contrary of Law of Demeter expectations :

  • One (Visitor) implies class structure to provide getter/setter so that Visitor can modify object's states without touching to class itself.

  • Other (Demeter) encourages to enclose all behavioral codes directly related to object in the same class.

So my question is :

When can we consider that a class is closed for modification and thus stop adding behavioral methods on it and so prefer to add them in a newly created Visitor with the great risk that client use getters/setters instead of behavioral methods already exposed before in initial class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单身狗的梦 2024-12-15 21:48:05

简短的回答是

首先,我不认为“告诉,不要问”说你应该删除所有你的 getter 和 setter,但是如果它们不增加任何价值或暴露内部状态。因此,举个例子,getter 应该尽可能尝试返回不可变的数据。 setter 的一个示例是调整或策略对象,这些是实例正常工作不需要的对象,但如果提供,它们会改变行为。

其次,我从未见过访问者模式的描述,该描述暗示被访问的对象应该具有 getter 和 setter,以便访问者可以修改它们。与任何其他对象一样,其想法是使用访问的对象公共 API 来执行任何扩展。暗示否则肯定也不利于封装。

在另一个主题上,我对你的最后一段有点困惑,因为我不知道你是在谈论开放/封闭原则,还是在谈论如何使用访问者模式构建功能。

需要注意的是,我认为关键是要理解 SOLID、德米特定律和所有其他实践都是良好实践,而不是最佳实践(“最佳实践”是一种营销学期)。如果您将这些实践中的任何一个发挥到极致,它们最终可能会损害代码的可读性或可维护性。

(顺便说一句,


这是个好问题:D)开放/封闭原则的好处主要适用于其他人以我们无法真正预料到的方式使用的代码(框架就是一个例子)。因此,如果您正在编写一个框架,则需要添加扩展点并使用语言功能来防止类被继承(例如 java 中的 final 或 C# 中的 seal),或者只是让开发人员重写某些方法。这个想法是为了防止天真的用户覆盖对象的重要部分并导致框架以意想不到的方式崩溃。一些语言/框架对此嗤之以鼻(例如Ruby/Rails),并鼓励用户打开类来添加或修改功能(取得了相当大的成功)。

如果您正在编写应用程序(并且您拥有代码),我建议您不要过多关注开放/封闭原则,而专注于应用德米特定律(在合理的范围内:D)。

The short answer is no.

First, I don't think "tell, don't ask" says that you should remove all your getters and setters, but that you should remove them if they don't add any value or expose the internal state. So, as an example, getters should try as much as possible to return immutable data. An example with setters is adjusment or policy objects, these are objects that are not needed for an instance to work properly, but if provided, they change the behaviour.

Second, I've never seen a description of the visitor pattern that implies that the visited object should have getters and setters, so the visitor can modify them. As with any other object, the idea is to use the visited object public API to do any extension. Implying otherwise definitely goes against encapsulation too.

On another subject, I'm a bit confused about your last paragraph, as I don't know if you're talking about the open/closed principle, or about how to build a feature using the visitor pattern.

One note, I think the key is to understand that SOLID, the Law of Demeter and all other practices are good practices rather than best practices ('best practices' is a marketing term). If you take any of these practices to the extreme, they will probably end up hurting the readability or maintainability of the code.

(by the way, nice question :D)


The benefit of the open/closed principle applies mostly to code that is going to be used by other people in ways that we can't really anticipate (frameworks are an example of this). So if you're writing a framework, you'll need to add extension points and use a language feature to prevent the class be inherited (such as final in java or sealed in C#) or by just letting the developer override certain methods. The idea is to prevent a naive user from overriding an important bit of an object and making the framework break in unexpected ways. Some languages/frameworks laugh at this (e.g Ruby/Rails) and they encourage the user to open the classes to add or modify features (with quite some success).

If you're writing an application (and you own the code), I would suggest you not pay too much attention to the open/closed principle, and focus on applying the Law of Demeter (to a sane extent :D).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文