c#业务应用程序中的不可变类

时间:2009-12-03 06:54:59

标签: c# immutability

我们在业务或数据库应用程序中为什么以及何时需要不可变(即只读)类(我不是在谈论string。我在谈论Business Objects?)

有人能给我一个场景的真实例子吗?

3 个答案:

答案 0 :(得分:12)

虽然Jon肯定会对不可变对象的好处做出令人信服的理由,但我会采取略微不同的方法。

当您在代码中对业务流程建模时,显然您要做的是使用代码中的机制来表示有关模型的事实。例如,如果客户是某种人,那么您可能拥有Person基类和Customer派生类,依此类推。

不可变性只是这些机制中的另一个。因此,在您的业务流程中,考虑一下发生的事情然后再发生变化,而不是随着时间的推移发生变化。

例如,考虑“客户”。顾客有一个名字。客户的名字是否有变化?当然。客户名称一直在变化,通常是在他们结婚时。那么,客户应该是一个不可变的类吗?可能不是。从逻辑上讲,当客户更改其名称时,您不会创建旧客户;旧客户和新客户是同一个对象,但name属性已更改。

现在考虑“合同”。合同是否会改变?不可以。现有合同的修订产生了一份新的,不同的合同。特定合同中的日期,当事人,条款等将及时冻结。合同对象可以是不可变的。

现在有趣的问题是当合同提到客户并且客户更改其名称时该怎么做。这是可变对象和不可变对象之间的交互,这使得这是一个棘手的设计问题。

答案 1 :(得分:5)

不可变类型比可变类型更易于推理 - 当您获得对实例的引用时,您知道可以依赖它而不是更改。你可以建立一种功能性的工作方式,你想要执行的任何突变变成一个创建新实例的操作(就像它对字符串一样) - 这些功能操作可以安全地组合,不用担心如果一个会发生什么操作以特定方式更改对象,这会损害其他操作。

根据不可变值的状态做出决定后,您知道该决策对该值仍然有效,因为该值本身将无法更改。

此外,不变性对于线程非常有用 - 当你想在多个线程中使用单个对象时,不变性避免了数据竞争等方面的许多问题。

许多这些好处对业务对象很有用,但您确实需要以不同的思维方式处理问题。特别是,如果您的数据库行不是不可变的(即您将修改行而不是总是创建行的“新版本”),那么您需要知道任何给定的值可能不再代表该行的数据库状态。

答案 2 :(得分:4)

打印完发票并将其发给客户后,该发票将永久冻结。任何调整都需要在后续发票上应用。