让我的getter方法改变存储值是不好的做法吗?

问题描述 投票:67回答:14

在我的班级中更改我的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;
 }
class lazy-loading lazy-evaluation getter-setter
14个回答
116
投票

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

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

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

或者,从null"N/A"的转换可以在setter中完成,即如果"N/A"通过则内部值可以设置为null


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


4
投票

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


3
投票

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

如果您定义合约以便不允许get() - 方法更改对象,那么您将违反自己的合同。考虑实现类似的方法

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

这种方法的优点是你不必检查get()的返回是“N / A”还是别的。这也可以在调用set()之前调用,以验证您不会在对象中插入非法值。

如果要设置默认值,则应在初始化期间执行此操作。


3
投票

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

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


3
投票

吸气剂的状态变化应该是悬而未决的罪行。这意味着客户端代码必须小心它访问getter和setter的顺序,并且为此必须知道实现。您应该能够以任何顺序调用getter并仍然获得相同的结果。当setter根据对象的当前状态修改传入值时,会出现相关问题。


2
投票

您可以为此目的使用一些价值持有人。像guava库中的Optional类一样。


38
投票

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

将更改放入setter

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;
}

11
投票

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


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方法中,永远不要改变对象的状态。我曾经参与过一些项目,并且经常必须让吸气剂const:“这种方法不能改变内部状态”。

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


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;
    }
 }

5
投票

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


4
投票

我会更好地更改setter方法,因此,如果值为null或为空,则将N/A指定给属性。因此,如果您在类中的其他方法(v.g.toString())中使用该属性,那么您将具有预期的值。

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

除此之外,没关系。


4
投票

我确实觉得这是一个不好的做法,除非你解释为什么你需要修改getter方法中的对象而不是在setter方法中进行它。 你觉得由于某种原因不能这样做吗?你能详细说明吗?


4
投票

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

但是如果你使用像Spring这样的框架,你必然会使用这些标准名称,你永远不应该将自定义代码放在其中。

© www.soinside.com 2019 - 2024. All rights reserved.