70

在我的课堂上更改我的 getter 方法(如第 2 版)是不好的做法。

版本 1:

 public String getMyValue(){
     return this.myValue
 }

版本 2:

 public String getMyValue(){

    if(this.myValue == null || this.myValue.isEmpty()){
       this.myValue = "N/A";
    }

    return this.myValue;
 }
4

14 回答 14

117

如果你的getter方法改变了对象的内部状态,我认为这实际上是一个非常糟糕的做法。

为了达到同样的效果,我建议只返回"N/A".

  • 一般来说,这个内部字段可能用于其他地方(内部),您不需要使用 getter 方法。所以最后,调用foo.getMyValue()实际上可以改变foo.

或者,从nullto的转换"N/A"可以在setter中完成,即内部值可以设置为"N/A"ifnull被传递。


一般性评论:
我只会添加状态,例如"N/A"某些 API 或其他依赖您的代码的实例是否期望它们。如果不是这种情况,您应该依赖您的编程语言中可用的标准空类型。

于 2012-12-14T09:51:52.750 回答
38

在我看来,除非你正在这样做lazy-loading(在那种情况下你不是),否则吸气剂不应该改变这个值。所以我要么:

将更改放入设置器中

public void setMyValue(String value) {
    if(value == null || value.isEmpty()){
        this.myValue = "N/A";
    } else {
        this.myValue = value;
    }
}

或者,如果值设置不正确,则让 getter 返回默认值:

public String getMyValue() {
    if(this.myvalue == null || this.myvalue.isEmpty()){
        return "N/A";
    }    
    return this.myValue;
}

在延迟加载的情况下,我会说在 getter 中更改您的成员很好,您可以执行以下操作:

public String getMyValue() {
    if (this.myvalue == null) {
        this.myvalue = loadMyValue();
    }    
    return this.myValue;
}
于 2012-12-14T09:50:26.173 回答
11

不,你在这里做两件事。获取和设置。

于 2012-12-14T14:53:27.393 回答
10

是的。这是一个不好的做法。

为什么?

当值被设置时(在构造函数或 setter 方法中),它应该被验证,而不是在调用 getter 方法时。为此创建一个private validate*方法也是一个好主意。

private boolean validateThisValue(String a) {
     return this.myValue != null && !this.myValue.isEmpty();
}

public void setThisValue(String a) {
    if (validateThisValue(a)) {
        this.myValue = a;
    } 
    else {
        // do something else
        // in this example will be
        this.myValue = "N/A";
    }
}

而且,在 getter 方法中,永远不要改变对象的状态。我做过一些项目,经常必须做getter const:“这种方法不能改变内部状态”。

至少,如果您不想使事情复杂化,在 getter 方法中,您应该返回 "N/A"而不是更改内部状态并设置myValue"N/A".

于 2012-12-14T10:04:48.567 回答
6

我通常定义一个特定的getter.

切勿更改原件getter

 public String getMyValue(){
     return this.myValue
 }

并创建一个特定的getter

public String getMyValueFormatted(){

    if(this.myvalue == null || this.myvalue.isEmpty()){
       return "N/A";
    }else{
       return this.myValue;
    }
 }
于 2012-12-14T17:48:11.063 回答
5

我认为最好初始化this.myValue = "N/A". 后续调用setMyValuethis.myValue根据您的业务条件进行修改。
不应该以getMyValue任何方式修改this.myValue。如果您需要返回某个值,则应返回该值(如“N/A”)而不是 alter this.myValue。Getter 不得修改成员的值。

于 2012-12-14T09:48:27.777 回答
4

我确实认为这是一种不好的做法,除非并且直到您解释为什么有必要在 getter 方法中修改对象而不是在 setter 方法中进行修改的原因。
您是否觉得由于某种原因无法做到这一点?你能详细说明一下吗?

于 2012-12-14T10:11:10.143 回答
4

做任何你喜欢的事。毕竟 getter 和 setter 只是另一种公共方法。您可以使用任何其他名称。

但是,如果您使用类似 的框架Spring,则必须使用这些标准名称,并且永远不要将自定义代码放入其中。

于 2012-12-14T12:41:51.937 回答
4

绝对是的,这是一种不好的做法。

想象一下,您通过网络与第三方(远程处理、COM、...)进行通信,这将增加往返行程,然后影响应用程序性能。

于 2012-12-14T17:56:50.923 回答
4

我会更好地更改 setter 方法,因此,如果值为null或为空,则将N/A分配给属性。因此,如果您在类 (vg toString()) 内的其他方法中使用该属性,您将在那里获得预期的值。

或者,更改 setter 方法以在设置的值不正确时启动异常,因此程序员被迫在设置值之前改进其处理。

除此之外,没关系。

于 2012-12-14T09:46:32.460 回答
4

setter 可以作为验证的一部分进行修改,但 getter 应该返回值并让调用者完成验证。如果您确实进行了验证,那么应该如何记录。

于 2012-12-15T01:58:06.823 回答
3

这实际上在很大程度上取决于您要使用 get() 方法执行的合同。根据按合同设计的约定,调用者必须确保满足先决条件(这意味着在 setter 方法中进行验证通常实际上是糟糕的设计)和被调用者(我不知道这是否是正确的英文术语即,被调用者)确保满足后置条件。

如果你定义了你的合约,使得 get() 方法不允许改变对象,那么你就违反了你自己的合约。考虑实现类似的方法

public isValid() {
    return (this.myvalue == null || this.myvalue.isEmpty());
}

这种方法的优点是您不必检查 get() 的返回是否为“N/A”或其他内容。这也可以在调用 set() 之前调用,以验证您没有在对象中插入非法值。

如果要设置默认值,则应在初始化期间进行。

于 2012-12-14T16:14:16.303 回答
3

getter 中的状态变化应该是一个悬而未决的罪行。这意味着客户端代码必须注意它访问 getter 和 setter 的顺序,并且要做到这一点,它必须了解实现。您应该能够以任何顺序调用 getter 并且仍然得到相同的结果。当设置器根据对象的当前状态修改传入值时,会出现相关问题。

于 2013-11-21T10:26:10.797 回答
2

您可以为此目的使用一些价值持有者。像番石榴库中的可选类。

于 2012-12-14T09:45:16.457 回答