无状态和不可变之间有什么区别?

时间:2012-10-19 19:10:44

标签: immutability stateless

我经常听到“无国籍”和“永恒”这个词。例如,HTTP是无状态协议,String对象是不可变对象。但我很难掌握两者之间的差异。当我创建无状态对象时,它不会在内部存储任何“状态”数据。如果我创建一个Immutable对象,它意味着它永远不会改变。

这是不是意味着同样的事情?

由于不可变对象不会改变,因此根据定义它不能具有状态。它永远是它。如果一个对象没有状态,则不能进行变异(根据定义)。因此,并非所有无状态对象都是不可变和不可变对象无状态的吗?

什么是可变无状态对象或不可变状态对象的示例?

4 个答案:

答案 0 :(得分:6)

上下文非常重要,此处有两个无关的概念。

“HTTP是无状态协议”意味着每个请求都没有其他请求的隐含知识,包括同一客户端发送的任何先前请求。这与FTP或SMTP之类的协议不同,在协议中建立连接然后发送不同的命令 - 每个命令/请求“关联”到同一客户端/连接。当然,状态/跟踪会通过添加回来。 cookie和跟踪URI,甚至流水线 - 但重点是HTTP协议中的每个请求都是“新的”和“分离的”。

“String是一个不可变对象”意味着特定对象的数据将始终与每个可观察方式的数据相同(这也意味着可观察属性不能< / em>被改变)。一些纯粹主义者可能认为它具有比这更深刻的含义,但实际上是关于可观察的属性 - 当不可变对象可以“包含”可变对象时,问题变得更加复杂。

(是的,通过技术性,具有无允许数据的对象 - 或状态 - 无法更新,因此是“不可变的”。但是,再次,上下文很重要谈论大象上的Fang牙或老虎的树干是很奇怪的。)

编辑:两者之间的差异

  

没有状态的对象是无状态的。所有无状态对象都是不可变的(因为没有任何变异);这是一种同义反复的技术性。对象可以具有状态并且仍然是不可变的 - 但是,具有状态(不可变或其他)的对象不能再被视为无状态。根据{{​​3}}:“[一个不可变对象]只有一个状态”,即初始状态。

     

- 来自comment on the linked answer

答案 1 :(得分:5)

没有。他们的意思不一样。

不可变对象永远不会改变。这并不意味着该对象中包含的数据不能表明国家。它只是意味着如果你想表示状态的变化,你需要创建一个新的对象。

无国籍意味着没有国家。

答案 2 :(得分:2)

我认为在某些情况下它是相同的,但我们只关注一些略有不同的方面。

当人们说“无国籍”意味着它没有国家时,它会让我发笑。当然,从某些角度来看,它有一些状态,例如无状态服务可以由复杂的对象图(依赖注入)支持。问题是网络协议具有略微不同的“状态”含义:它取决于先前的请求/响应。但是,根据定义,不可变服务也不依赖于以前的调用。

“无状态”并不总是与HTTP协议相关,我们可以使用相同的术语在闪亮的OOP代码中争论服务对象中的setter。在这里你可以看到这两个术语实际上是相同的:不可变服务是无状态服务,反之亦然。

但是,对于我来说,调用值对象“无状态对象”是很尴尬的。听起来很糟糕。

回顾:如果是服务(网络或OOP,无关紧要),我会说这些术语是可以互换的。

只是示例:

interface Logger
{
    public function logWarning(string $message);
    public function logError(string $message);
}

我们拨打logWarninglogError的次数并不重要,呼叫顺序也无关紧要。因此,我们可以称之为“无国籍服务”。

但是这项服务也没有任何设定者和任何类似changeFileName()的变换器 - &gt;它是一个不可变的服务/对象。

Mutability使对象有状态。 有状态使对象变得可变。 这些术语在服务方面是相互依存的。

答案 3 :(得分:1)

他们肯定不一样。

不可变对象永远不会改变。永远不会修改不可变对象的状态,别名不可变对象是无害的,并且不可变对象不需要别名控制,尽管可能需要别名控制来证明对象实际上是不可变的。

无国籍意味着没有国家。 HTTP被称为无状态协议,因为每个命令都是独立执行的,不需要知道它之前的命令。它基于请求范例。在该协议中,通信通常通过TCP / IP协议进行。