【问题标题】:Should methods be destructive in custom objects?方法应该在自定义对象中具有破坏性吗?
【发布时间】:2009-03-09 21:07:57
【问题描述】:
我必须实施 Java.Polynomial 作为学校作业。部分方法有add(polynomial)、multiply(polynomial)等
如果是这样的情况
p.add(q); // computes p + q
返回 void 并将多项式的总和保留在 p 中会更好吗?还是返回多项式并保持以前的 p 值不变更好?
我的直觉告诉我应该做以下事情
- 将 p.add(q) 实现为“破坏性”方法...它将 q 添加到 p 的值并将总和存储在 p 中
- 还实现了一个静态方法 Polynomial.add(p,q),它返回多项式的总和。
你怎么看?
【问题讨论】:
标签:
java
oop
polynomial-math
【解决方案1】:
我个人非常喜欢不可变类型。我会写 p.plus(q) 而不是 p.add(q) 并让它返回一个新的多项式。不变性有很多好处,不仅在线程安全方面(听起来在这种情况下不会成为问题),而且在对代码的推理方面。如果你知道一旦你隐藏了对它的引用,就不会改变你脚下对象的内容,那么预测会发生什么会容易得多。
【解决方案2】:
这是风格问题。当对象是不可变的时通常会更好(并且“更整洁”),因此方法不是“破坏性的”(它们不是变异器,它们没有副作用)而是返回具有新值的新实例。
最著名的不可变类是 String。
【解决方案3】:
"最好返回一个多项式,并保持以前的 p 值不变"
如果你让你的数字类型表现得像其他数字一样,生活会更好。
当您必须通过减少内存分配来优化性能时,“破坏性”操作是必不可少的。
权衡是由于变量中看起来更复杂的状态变化,您的处理变得不透明。您不希望隐藏状态更改;你希望你对变量的赋值是一个大的、明显的一流的、带有-an-=的东西。
【解决方案4】:
所以每个人都说你应该让它不可变,除非有非常具体的性能原因让它可变(你将在一个魔术多项式上添加十亿多项式并且不想要内存分配),不可变是要走的路。
如果您有真正的性能原因,您可能想要一个破坏性和非破坏性版本,但请记住 - 这会导致混淆。我认为您关于重载添加的想法是否具有破坏性或不基于数量将使事情变得非常非常混乱。如果您愿意,最好让一切都成为非破坏性的,并制作一个 addDestructive(poly p) 方法。
【解决方案5】:
即使您使用“破坏性”方法,您还是希望返回新值以允许函数链接。而且,对于它的价值,当面对 BigInteger 和 BigDecimal 的相同问题时,Sun 决定采用非破坏性。
【解决方案6】:
使其不可变,并使接口与 BigInteger 相同(尽可能适用)。
【解决方案7】:
返回 void 并将多项式之和保留在 p 中会更好吗?
不错,也不一定更好。
还是返回一个多项式并保持以前的 p 值不变更好?
更好,更少的惊喜和更容易理解和维护的代码。 (尽管您将不得不创建更多变量)
【解决方案8】:
多项式的变量值是固定的,因此只有不可变才有意义。为您的操作返回一个新的多项式。