对象内的链接是否被视为反模式

本文关键字:模式 是否 链接 对象 | 更新日期: 2023-09-27 17:57:15

假设你有一个经常(甚至专门)用作链表一部分的类。将链接信息放置在对象内是一种反模式吗?

例如:

  公共类项目   {       私人项目上一个;       接下来是私人项目;       ...   }

一个经常被引用的建议是简单地使用通用容器类(例如 Java 中的 java.util.LinkedList),但这会产生具有单独节点对象的开销(并且链接对象不能轻易引用其同级对象)。

思潮?

对象内的链接是否被视为反模式

它不一定是反模式。 反模式必须具有负面的副作用才能获得"反"的权利。

例如,Tree数据结构中的Node需要将其链接缓存在Node内。 其他任何事情都会违反更重要的概念,即基于对象责任的数据和代码的封装和本地化。

另一方面,嵌入其"下一个"客户的Customer数据结构意味着Customer数据结构正在处理两个不相关的职责,即维护Customer数据和维护Customer的列表数据结构。 在这种情况下,这两种责任可能会以影响维护便利性的方式混合在一起;因此,将被视为一种反模式。

我想是的。 在我看来,您正在混合职责(例如,如果您的对象反映员工,我希望只看到与员工相关的属性和方法,而不是与链表相关的方法和属性)。

有时,一点开销是拥有"更清洁"设计的成本。 您是否愿意为这笔开销付费是一个不同的问题。 在我看来,使用内置链表等实用程序增加的少量开销是值得的......它节省了开发时间,经过全面测试,设计更简洁。

如果它并不总是在链表中使用,则它是一种反模式。如果您向类中添加可能需要的属性/方法,您最终将拥有一支瑞士军队。阅读有关 YAGNI 的信息。

添加这些方法也会破坏 SRP,因为该项目还将负责跟踪其同级。

一般来说,这是建议不要这样做的,因为您将来需要的功能会逐渐增加。 即使您目前不需要"搜索"和"排序"等功能,总有一天规格会发生变化,您需要对项目进行排序。 如果以这种方式实现它,现在您需要实现排序。

包含的链表之所以存在,是因为它们已经过尝试、信任和调试。 为这些编写自己的函数只是重复大量不必要的工作。

此外,您对额外对象节点开销的担忧不应该太担心 - 它可能有多少额外的开销? 在像今天这样的日子里,即使它们是一千字节(这将是疯狂的),也不应该让人担心。

我相信java中的XML DOM类可以(类似于)您所描述的,因此至少有先例。通常,您描述的内容可能是例外而不是规则,否则您最终只会重新实现链表。

在Java中,它比其他语言问题更少,因为Item必须是类指针。 另一方面,如果Item是结构体,就像 C# 和其他语言一样,则会遇到明显的问题。 除了你有一个可变结构的事实之外,你还可能会在尝试定义一个具有无限大内存要求的结构时遇到编译时错误。

根据要求,允许对象通过下一个和上一个引用其同级可能要简单得多,就像层次结构中的对象通常可以通过引用它的父级来引用它的父级一样。

这种模式称为侵入性容器

这并非在所有情况下都是正确的做法,但它具有一些众所周知的优点(更低的内存使用率、更好的局部性、内存管理器要分配和收集的对象更少)。

与往常一样,这取决于项目的范围和/或使用它的上下文。如果项目相当小,遵循每一个良好的实践指南不会很有帮助:你最终只会花更多的时间"正确"地做它,而且好处可能几乎为零。

如果你的项目有点大,但这个链表只在本地使用,比如在单个源文件中,或者作为类的私有成员(换句话说,如果它是一个实现细节,而不是总体机制的一部分),那么你也可以跳过"正确"地这样做,采取更简单的方法。

只有当项目很大并且链表是拼图的重要组成部分时,您才应该花时间尽可能完美地完成它。根据经验,如果多个源文件需要此链表,请正确执行,不要偷工减料。

一般来说,知道何时以及如何花费你的精力。在编写正确和健壮的代码与过度工程之间有一条非常细的界限。