State 学习如何避免OOP中的副作用和状态的最佳资源是什么?

State 学习如何避免OOP中的副作用和状态的最佳资源是什么?,state,side-effects,State,Side Effects,我最近一直在玩函数式编程,在副作用、为什么应该包含这些副作用等方面有很好的处理方法。在使用OOP的项目中,我正在寻找一些资源,其中列出了一些最小化副作用和/或状态的策略 这方面的一个很好的例子是《RESTfulWeb服务》一书,它为您提供了最小化Web应用程序中状态的策略。还有什么其他的存在 请记住,我不是在寻找另一本面向对象分析/设计模式的书(尽管良好的封装和松耦合有助于避免副作用),而是一本主题本身就是状态/副作用的资源 一些汇编的答案 大多数关心状态的OOP程序员这样做是因为并发性,所以

我最近一直在玩函数式编程,在副作用、为什么应该包含这些副作用等方面有很好的处理方法。在使用OOP的项目中,我正在寻找一些资源,其中列出了一些最小化副作用和/或状态的策略

这方面的一个很好的例子是《RESTfulWeb服务》一书,它为您提供了最小化Web应用程序中状态的策略。还有什么其他的存在

请记住,我不是在寻找另一本面向对象分析/设计模式的书(尽管良好的封装和松耦合有助于避免副作用),而是一本主题本身就是状态/副作用的资源

一些汇编的答案

  • 大多数关心状态的OOP程序员这样做是因为并发性,所以请阅读。[正是我想要的]
  • 使用TDD使副作用更加明显[我喜欢它,例如:设置越大,运行测试所需的状态就越多=良好警告]
  • [好东西,防止了更改通常令人困惑的函数参数的副作用]
  • 方法只做一件事,如果它们更改对象的状态使其简单明了,则可能使用描述性名称
  • [我真的很喜欢这个]
  • 将值作为参数传递,而不是将其存储在成员变量中。[我不把这一点联系起来;它会把函数原型弄得乱七八糟,而且干净的代码和其他书籍会积极地阻止它,尽管我承认这有助于解决状态问题]
  • 重新计算值,而不是存储和更新它们[我也很喜欢这样;在我工作的应用程序中,性能是一个次要问题]
  • 同样,如果可以避免,不要复制状态。让一个对象负责保存它,并让其他人在那里访问它。[基本OOP原则,好建议]

我认为规则非常简单:方法只能做一件事,并且应该在方法名称中清楚地传达意图


方法应该查询或更改数据,但决不能两者兼而有之。

我认为在面向对象的世界中,你不会找到很多关于这个主题的最新资料,因为面向对象编程(以及最重要的编程)依赖于状态和副作用。例如,考虑日志记录。这纯粹是副作用,但在任何自尊的J2EE应用程序中,它无处不在。Hoare最初的快速排序依赖于可变状态,因为您必须围绕轴心交换值,但它也无处不在

这就是为什么许多OO程序员很难理解函数式编程范式。他们试图重新分配“x”的值,发现这是不可能的(至少在他们使用过的其他语言中是不可能的),然后他们举起手喊“这是不可能的!”最后,如果他们有耐心,他们会学习递归和咖喱,以及映射函数如何取代循环的需要,然后他们会平静下来。但对于一些人来说,学习曲线可能非常陡峭


现在最关心避免状态的OO程序员是那些处理并发的程序员。原因很明显——当您试图管理线程之间的并发时,可变状态和副作用会造成巨大的麻烦。因此,我在OO世界中看到的关于避免状态的最佳讨论是

在OO中隔离副作用的一种方法是让操作只返回要引起的副作用的描述对象

这是一种接近于这种想法的模式


通过实践TDD(或至少编写单元测试),人们通常会更清楚地意识到副作用,并更谨慎地使用它们,还可以将它们与其他易于编写数据驱动(预期、实际)单元测试的无副作用表达式分开。

我做的一些小事情:

  • 喜欢不变的状态,它是相对良性的。例如,在Java中,我将成员变量设为final,并尽可能在构造函数中设置它们

  • 将值作为参数传递,而不是存储在成员变量中

  • 重新计算值,而不是存储和更新它们,如果这样做足够便宜的话。这有助于通过忘记更新数据来避免不一致的数据

  • 同样,如果可以避免,不要复制状态。让一个对象负责保存它,并让其他人在那里访问它


我不太明白您的意思是什么样的副作用,以及您在这种情况下对状态(在静态状态下属于协议,而不是编程范式)的意思。我认为,“避免”副作用和状态并不是您真正的意思。您所说的“状态”到底是什么意思?对象在任何给定点的实例成员的值,加上对象类的任何静态成员的值?因为这是OOP中非常重要的一部分,除非您打算将所有数据存储在全局变量中。@Cat:对于“状态”,我很确定OP的意思是“可变状态”。@Benjol-不确定您的意思。例如,您可以用OOP语言编写一个功能完整的应用程序,而不产生任何状态或副作用(请参阅Clojure)。实际上,有些副作用是需要的,或者你只是有一个“刚热起来的黑匣子”,所以你在使用它们的时候会尝试清楚地标记它们。我的问题是,在OOD中“清楚地标记它们”/“包含它们”/“最小化它们”的策略是什么?我喜欢让对象不变的建议。我找到了这个参考资料:嘿,我没有读过那个,但我在别处读过。当你看到人们不遵守规则,因为事情变得很难理解,然后他们想知道为什么他们的代码没有按应有的方式运行时,你会感到沮丧。