oop - 模式访客违反得墨忒耳定律?

标签 oop design-patterns visitor-pattern

得墨忒耳法则期望在类之间建立最松散的耦合。

这意味着在类中公开的所有 getter/setter 中的 90% 必须被“删除”并替换为“包含行为”的方法。事实上,它对应于“告诉,不问”的理念,因为不期望客户通过糟糕的 getter/setter 方法来处理行为本身。
如果在其他地方使用相同的操作,这也会减少重复的代码。

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

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

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



所以,乍一看,这似乎与得墨忒耳法则的预期相反:
  • 一(访问者)意味着类结构提供getter/setter,以便访问者可以修改对象的状态而不接触类本身。
  • 其他(Demeter)鼓励将与对象直接相关的所有行为代码包含在同一类中。

  • 所以我的问题是:

    我们什么时候可以考虑关闭一个类以进行修改并因此停止在其上添加行为方法,因此更愿意将它们添加到新创建的访问者中?

    最佳答案

    简短的回答是没有 .

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

    其次,我从未见过访问者模式的描述暗示访问对象应该具有 getter 和 setter,因此访问者可以修改它们。与 一样任意 其他对象,想法是使用访问对象公共(public) API 来做任何扩展。暗示否则肯定也违背了封装。

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

    请注意,我认为关键是要了解 SOLID、得墨忒耳法则和所有其他实践都是 良好做法而不是 最佳实践 (“最佳实践”是一个营销术语)。如果您将这些实践中的任何一种发挥到极致,它们最终可能会损害代码的可读性或可维护性。

    (顺便说一句,好问题:D)

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

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

    关于oop - 模式访客违反得墨忒耳定律?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7703595/

    相关文章:

    python - 为什么一个类需要 __iter__() 来返回一个迭代器?

    java - Scala 重载不选择最具体的方法

    ios - 这里需要代表吗?

    C# 和设计模式 - 需要一个优雅的解决方案来解决常见问题

    c++ - 访问者或节点中的 AST 遍历?

    带有智能指针的 C++ 访问者模式

    c++ - 传递用于结构定义的参数

    父类不能在静态上下文中使用 PHP const/static 变量

    c# - 依赖容器 : how to instantiate object instances

    Java - 同一类结构的多个访问者模式