为什么不直接使用属性而是使用 getXXX() 方法

发布于 2024-12-11 10:07:06 字数 699 浏览 0 评论 0原文

有些领域对象的方法中,并没有直接使用属性,而是使用get方法。为什么 ?举例如下:

private List<String> errorCodeList = new ArrayList<String>();  

/** 
 * Add all errors to the error list.
 */
public void addAllErrors(Collection<String> theErrorStrings) {
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}


/**
 * @return the errorCodes
 */
public List<String> getErrorCodeList() {
    return errorCodeList;
}
/**
 * Set the error strings.
  */
public void setErrorCodeList(List<String> allErrors) {
    this.errorCodeList = allErrors;
}

In some domain object's method , they didn't use the attribute directly, but use the get method . Why ? One example as follows:

private List<String> errorCodeList = new ArrayList<String>();  

/** 
 * Add all errors to the error list.
 */
public void addAllErrors(Collection<String> theErrorStrings) {
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}


/**
 * @return the errorCodes
 */
public List<String> getErrorCodeList() {
    return errorCodeList;
}
/**
 * Set the error strings.
  */
public void setErrorCodeList(List<String> allErrors) {
    this.errorCodeList = allErrors;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天煞孤星 2024-12-18 10:07:06

这是封装的问题。通过仅通过 getter 和 setter 提供对实例变量的访问,您可以隐藏内部表示。因此,您可以随后更改实现,而无需修改接口。您可能会认为使用 HashMap 来存储错误代码(无论出于何种原因)会更方便,并且一旦您更改了它,访问该字段的所有代码都会中断。但是,如果您提供了 getter 和 setter,则无论您更改了内部表示,您都可以保持它们原样。

此外,还可以更轻松地确保不变量保持在适当的位置,而如果每个人都可以访问这些字段,则无法做到这一点。

It's a matter of encapsulation. By providing access to instance variables only via getters and setters you hide the internal representation. Thus you are able to change the implementation afterwards without modifying the interface. You might decide that it would be more convenient to use a HashMap to store the error codes (for whatever reason) and once you changed that, all code accessing the field would break. If you provided getter and setter however, you are able to keep them as they are in spite of your changed internal representation.

In addition to it is easier to ensure that invariants are kept in place, which you were unable to do if everybody could access the fields.

梦回梦里 2024-12-18 10:07:06

我个人不喜欢通过 getter 方法访问同一类中的字段:避免调用 getter 不会破坏封装,因为您是在同一类定义中编写代码。此外,使用 getter 会使代码看起来更加混乱,并且不能提供有效的语法突出显示。

显然有一些例外情况,您必须通过 getter 访问该字段:

  • 当它是延迟创建时。
  • 当 getter 动态计算一个值时。

I'm personally not a fan of accessing fields within the same class via their getter methods: Encapsulation is not being broken by avoiding calling the getter because you're writing code within the same class definition. Also, using getters makes the code look more cluttered and doesn't provide effective syntax highlighting.

There are obviously exceptions where you have to access the field through a getter:

  • When it's lazily created.
  • When the getter calculates a value on the fly.
美男兮 2024-12-18 10:07:06

我认为示例代码不是最好的方法:变量是通过相同方法的 getter 直接访问的 - 这种混合有点令人困惑。
如果列表的惰性创建是在 getter 中完成的,以及使用 getter 的原因,那就更清楚了。例子:

public void addAllErrors(Collection<String> theErrorStrings) {
    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}

public List<String> getErrorCodeList() {
    // TODO synchronization?
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    return errorCodeList;
}

I think the sample code is not the best way to do it: the variable is being accessed directly and through the getter in the same method - this mixing is kind of confusing.
It would be clearer if the lazy creation of the list was done in the getter and a reason to use the getter. Example:

public void addAllErrors(Collection<String> theErrorStrings) {
    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}

public List<String> getErrorCodeList() {
    // TODO synchronization?
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    return errorCodeList;
}
偏爱自由 2024-12-18 10:07:06

那就是封装:

封装可以被描述为一个保护屏障,可以防止
代码和数据被定义的其他代码随机访问
课外。对数据和代码的访问受到严格控制
通过接口。

更多信息请参见此处

That is encapsulation:

Encapsulation can be described as a protective barrier that prevents
the code and data being randomly accessed by other code defined
outside the class. Access to the data and code is tightly controlled
by an interface.

More information available here.

后来的我们 2024-12-18 10:07:06

如果 getter 存在的话,在调用中使用 getter 可以被认为是一个好的实践。这是因为,如果 getter 背后的实现要更改使用 getter 的类中的其余代码,则不需要更改。

它还可以简化静态代码分析,因为对字段的所有访问(无论是从类内部还是从类外部)都是通过单个方法完成的。

当然,需要权衡额外的方法调用(除非编译器足够聪明来进行转换)。

也就是说,我同意亚当斯基的观点,我也不喜欢这个。

It can be considered good practice to use a getter within a call is the getter exists. This is because if the implementation behind the getter were to change the rest of the code in the class that uses the getter would not need to change.

It also can ease static code analysis since all access to the field (either from within the class or without) are done via a single method.

There of course is the trade off of the extra method call (unless the compiler is smart enough to do the conversion).

That said, I agree with Adamski, I am not a fan of this either.

白色秋天 2024-12-18 10:07:06

直接访问数据成员不会破坏封装,但是几个月后,数据成员更改语义,您必须在直接访问该字段的一百个派生类中进行搜索,以确保没有什么破裂吗?如果访问仅通过 getter 完成,则跟踪每个字段的访问位置会容易得多。

Encapsulation won't be broken by directly accessing data members, but what about, after a couple of month, a data member change semantics and you've got to search in one hundred derived classes where that field was accessed directly just to be sure that nothing breaks up ? If access is solely done via getter, it's a lot easier to track where each field is accessed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文