8

我正在做代码审查,我注意到这样的代码:

@Entity
@Table(name = "SOME_TABLE")
public class SomeReportClass {

@Column(name = "REPORT_NUMBER", length = 6, nullable = false)
private String reportNumber;

.....
    public String getReportNumber() {
        return reportNumber;
    }

    public void setReportNumber(String reportNumber) {
        this.reportNumber = StringUtils.trimToNull(reportNumber);
    }

}

每次我看到在二传手内部进行修剪时,我都觉得这不是最清晰的解决方案——这个问题的一般做法是什么?

4

4 回答 4

4

如果您知道您总是需要修剪该值,则此方案将避免代码重复,即在您设置之前您必须始终修剪并担心您错过了修剪的地方。在我看来,将它放在 setter 中是一个很好的做法

于 2013-11-08T09:49:23.700 回答
1

除了透明地设置值之外,使用 setter 来做任何其他事情违反了关注点分离的原则:通过这种设计,您永远将设置关注点与修剪关注点交织在一起。这一切都很棒而且很漂亮——只要你 100% 确定在你的程序的整个生命周期内,你永远不会有一个你想要没有修剪的设置的用例。一旦你确实需要它,这种设计的失败模式就非常可悲:你将拥有一个set实际上是“特殊”的常规方法,并被迫添加另一种setWithoutTrimming方法,这与新程序员的任何理智假设完全相反。

更一般地说,我的选择是使用纯公共字段(Hibernate 支持它们,以及 Spring、Jackson 等),这使得设置它们的语义非常清楚。如果我还有其他顾虑,例如修剪,那么我会使用对静态方法(纯函数)的显式调用,该方法会进行必要的转换。这导致了清晰和明显的设计,没有诸如“为什么 getter 返回与我刚刚设置的值不同的值?”之类的 WAT。

于 2013-11-08T10:03:45.213 回答
0

这段代码没问题。setter 优于公共值的原因是,您可以在其中引入任何逻辑而不会破坏类的接口。我只有一个注释,如果你在 setter 中修剪字符串,那么你应该总是在 getter 中修剪它。在你目前的情况下,你有一个问题:

  1. 获取任何空白值
  2. 放回去
  3. 然后尝试再次获取

第一次和最后一次得到会有所不同。如果可以从外部实体填充表,则这是可能的。

于 2013-11-08T10:19:53.483 回答
0

我觉得只要方法记录清楚,里面的逻辑就可以了。

归根结底,您不希望在调用 setter 之前在代码中执行修剪的大量位置。

如果您以后决定不再需要修剪字符串,则只需进行一项更改。

毕竟,封装的重点是将数据和该数据上的行为放在同一个地方。

于 2013-11-08T09:51:33.897 回答