如何避免副作用?

时间:2011-10-27 16:51:09

标签: java side-effects

为避免副作用: 我不希望在我的方法中更改pramaeter对象属性值。我更喜欢创建一个代表结果并将其返回的新结构。

避免副作用在多线程环境中才真正重要,但仍然是很好的做法。 f(X)= Y,能够比较两个对象,你作为参数接收的对象和作为结果给出的对象是好的。

这意味着,我需要将IN参数对象中的所有属性映射到我创建的OUT新实例对象。这将使一些代码如下:

groundCertResult.setExpirationDate(pGroundCertificate.getExpirationDate());
groundCertResult.setValidationDate(pGroundCertificate.getValidationDate());
groundCertResult.setId(pGroundCertificate.getId());

它可以在我的方法中创建很多行:$

我也可以不用映射那么多值,只需添加一行

//use findByID without mapping that much 
final GroundCertificate groundCertResult =
    groundCertificateDao.findById(pGroundCertificate.getId());

但最终会访问数据库并进行更多处理。

使用反射做一些通用方法,将对象映射到另一个?在性能方面,这将是很大的。

你会选择什么?延长项目需求。考虑到可维护性,可扩展性......

2 个答案:

答案 0 :(得分:1)

  1. 您可能需要查看CloneableObject.clone()。如果对象的浅表副本足够,则无需编写任何其他代码。 Object.clone()会为您做到这一点。
  2. 确保您真的想要/需要这种方法。如果您不确定是否会发生副作用,请查看您的代码以了解相关信息。
  3. 保持一致。不要在实现中混合使用复制和修改操作。
  4. 如果您或某人想要使用GroundCertificate的后代,请考虑需要做些什么。

答案 1 :(得分:0)

它不仅在多线程环境中很好,尽管导致问题的副作用的风险也大大降低。

副作用增加了推理代码实际执行的难度。你需要确定状态可以改变的所有地方,没有办法解决所有事情并确定那些地方。 “远处的幽灵行动。”

有几个库可以执行各种类型的bean属性副本,例如Apache的BeanUtils。从效率的角度来看是否值得,取决于具体情况。

虽然它不是一种“纯粹”的方法,但我也没有强烈反对返回修改后的参数对象,只要清楚原始对象被修改即可。通常情况下,我将参数对象设置回该值。如果我不是,我会尝试通过链接某种复制功能来指示代码。

归根结底,对我而言,这完全取决于清晰度,当我被迫这样做时,我会清楚地了解纯度,这是安全的。