我看到了使程序中的对象不变的好处。当我真正地为自己的应用程序考虑一个好的设计时,我常常自然而然地想到我的许多对象都是不可变的。我常常想让所有对象保持不变。
这个问题涉及相同的想法,但没有答案表明什么是不变性的好方法以及何时实际使用它。是否有一些好的不变设计模式?总体思路似乎是“使对象不可变,除非您绝对需要更改它们”,这在实践中毫无用处。
我的经验是,不变性将我的代码越来越多地驱动到功能范式,并且这种发展总是会发生:
- 我开始需要持久性(在功能上)数据结构,例如列表,地图等。
- 使用交叉引用非常不方便(例如,树节点引用其子节点,而子节点引用其父节点),这使我根本不使用交叉引用,这又使我的数据结构和代码更具功能性。
- 继承不再有任何意义,我开始改用合成。
- OOP的整个基本概念(如封装)开始瓦解,而我的对象开始看起来像函数。
在这一点上,我几乎不再使用OOP范例中的任何内容,而可以切换到纯函数式语言。因此,我的问题是:是否有一种一致的方法来进行良好的不可变OOP设计,或者总是总是这样,当您将不可变的想法发挥到最大潜力时,您总是最终会使用一种功能语言进行编程,而该语言不再需要OOP世界中的任何东西?是否有任何好的指导方针来决定哪些类应该是不可变的,哪些应该保持可变以确保OOP不会崩溃?
为了方便起见,我将提供一个示例。让我们拥有一个ChessBoard
不可变棋子的不可变集合(扩展抽象类)Piece
)。从OOP的角度来看,一块负责从板上的位置生成有效的移动。但是要生成移动,棋子需要引用其棋盘,而棋盘需要引用其棋盘。好了,有一些技巧可以根据您的OOP语言创建这些不可变的交叉引用,但是它们很难管理,最好不要用它来引用其董事会。但是由于不知道棋盘的状态,所以棋子无法产生移动。然后,片段变成仅包含片段类型及其位置的数据结构。然后,您可以使用多态函数来生成各种片段的移动。这在函数式编程中是完全可以实现的,但是如果没有运行时类型检查和其他不良的OOP惯例,在OOP中几乎是不可能的...然后,