4

我刚刚完成了一个奇怪的 UI 效果的六个小时的调试会话,我发现我最喜欢的框架实现的一个名为“getVisibleRegion”的接口函数禁用了一些 UI 功能(并且显然忘记了恢复它)。

我已经向框架提交了一个错误,但这让我想到了适当的设计:在什么情况下对一个名称暗示仅仅是计算/获取操作的操作产生任何副作用是合法的?

对于那些对实际细节感兴趣的人:我有一个关于我的插件不断破坏 Eclipse 的代码折叠导致折叠栏消失并且无法“展开”或查看折叠代码的错误的报告。我将其追溯到对 ITextViewer 上的 getVisibleRegion() 的调用,该 ITextViewer 的类型表示源代码查看器。现在,ITextViewer 的文档确实声明“实现 ITextViewerExtension5 的查看器可能被迫更改显示的输入文档的部分,以履行此合同”。然而,实际的实现有点过于宽松了,只是永久禁用了投影(折叠),永远不会把它带回来。

4

5 回答 5

5

我能想到的最大原因是缓存结果。

于 2008-12-10T02:08:31.067 回答
3

我会说没有。

于 2008-12-10T01:58:27.017 回答
2

这可能是一种极端情况,它甚至不能算作副作用,但如果计算结果缓存在对象中,那么这是可以接受的。即便如此,它不应该对调用者产生影响。

于 2008-12-10T02:07:37.433 回答
2

我会说只有当副作用非常明显时才会发生。这是一个简单的例子:

  MakeMyLifeEasyObject mmleo = new MakeMyLifeEasyObject(x, y, z, default, 12, something);

  Object uniqueObjectOne = mmleo.getNewUniqueObject();
  Object uniqueObjectTwo = mmleo.getNewUniqueObject();

  System.out.println(uniqueObjectOne.getId() == uniqueObjectTwo.getId()); // Prints "false"

现在在我的理论中,MakeMyLifeEasyObject 有一些内部计数器(如数据库表上的主键)。get 有一个副作用。我也可以想出这样的想法:

  Object thing = list.getNextObjectAndRemoveFromList();

那也是有道理的。

现在需要注意的是,在这两种情况下,最好重命名方法

第一个可能会更好,如 createNewUniqueObject(),而第二个不同的名称(在本例中为 pop())会更好。

当它不是我上面给出的一些半人为的例子时,我会说如果值需要很长时间才能创建或可能会被使用很多并且需要,那么应该发生的唯一副作用是创建/更新一些缓存被加速。

这方面的一个例子是一个包含一堆字符串的对象。您有一个方法 getThingToPrint() 需要将一堆连接在一起。你可以在调用时创建一个缓存,这将是一个副作用。当您更新事物所基于的字符串之一时,该集合将使缓存无效(或更新它)。

和你描述的一样吗?绝对听起来像一个错误。我想不出一个好主意的情况。如果这是预期的行为而不是错误,那么应该将其重命名为其他名称(即 disableThingAndGetVisibleRegion())。

于 2008-12-10T02:17:55.540 回答
0

obj.getBusyDoingStuff()

于 2008-12-10T02:02:53.030 回答