无状态对象是好的实践还是不好的实践?

4
这是我对无状态对象的理解:任何从没有类变量的类创建的对象都是无状态对象。我的问题是什么时候应该编写无状态类?拥有无状态对象是一个好习惯吗?

1
你需要它们吗?或者更准确地说,当你不需要(暴露)状态时。 - Hot Licks
例如,看看java.lang.Math:如果它是一个有状态的类,你必须创建一个Math实例来计算余弦值,这有任何意义吗? - Hot Licks
你可能想把你的静态工具方法放在一个单独的类中。 - PM 77-1
尽管应该注意到,如果您发现自己创建了许多无状态类,则可能没有按照正确的方式将工作数据分区为类。 - Hot Licks
2
你对“无状态对象”的定义是错误的:通常,“类变量”(或类成员)指的是静态成员。然而,你所说的似乎是“实例变量”。 - Adrian Shum
显示剩余3条评论
2个回答

7
无状态对象在需要“将功能作为参数传递”的情况下非常有用。由于函数不是Java中的对象,因此将一个带有函数的对象作为参数传递是一种实用的方式。
例如,如果一个类没有实现Comparable或者您需要支持使用不同的“<”关系定义进行排序,则可以使用Comparator进行排序(例如按升序/降序排序;按不同属性排序...)。
工厂(请参见http://www.oodesign.com/factory-pattern.html)可能是一个无状态对象。工厂的所有函数都可以创建对象,并且创建这些对象所需的所有参数都可以作为工厂函数的参数给出。

1

通常情况下,如果你拥有的是无状态的(没有实例变量,只有类变量),它没有理由被实例化,也不应该是一个对象(尽管将其实现为一个类可以有助于将相关功能组合在一起,并管理对静态类变量的访问)。

在我看来,唯一正当使用无状态对象的情况是当它是接口的一个微不足道的实现。例如,一个不可变集合(例如EmptyCollection)可能希望成为一个对象,以便像其他集合对象一样传递和操作,但可以实现为无状态,因为它是不可变的,其状态永远不能改变。


这将是不可变的,但不是无状态的。您可能实现真正无状态对象的情况是,当您想要传递“行为”作为参数时,而没有任何相关的“状态”。例如,您可能有一个包,可以传递多个不同的排序行为之一。 - Hot Licks
有人可能会对不可变行为是否可以在任何合理意义上被认为是“状态”进行争论 - “返回0”通常不被认为是状态 - 但我承认你的观点;无论如何,那是一个更好的例子。 - keshlam
一个字符串无疑是一个有状态的对象,但是它是不可变的。 - Hot Licks
同意。不变性是不够的。但是,如果您正在实现一个版本的CharSequence,该版本通过类设计始终显示为值“Foo”,我会将其称为无状态,因为您甚至不能在构造函数时间设置它。硬编码常量对象有时是有用的优化。我们同意捆绑行为对象是更好的例子。 - keshlam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接