JavaBeans 的设计如何与信息隐藏相结合?
两个学期前,一位教授对我说:
有些人被告知要始终为所有私有实例变量包含 setter 和 getter 方法。我说这会破坏信息隐藏,并且通常会导致系统无法强制执行不变量。
现在,这对我来说听起来不错。但是,包含这些类型的 setter/getter 不是创建 JavaBean 的核心部分吗?如果是这样,为什么?如果不是,我对 JavaBeans 有何误解?
Two semesters ago, I had a professor who said:
Some of you have been told to always include setter and getter methods for all private instance variables. I say that this breaks information hiding, and often results in systems where invariants cannot be enforced.
Now, that sounds right to me. But isn't including those kinds of setters/getters a core part of creating JavaBeans? If so, why? If not, what am I misunderstanding about JavaBeans?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Java Bean 类中不需要 getter 和 setter。所需要的只是该类必须是公共的,它必须有一个公共的无参数构造函数,并且它必须实现 Serialized。然而,为了在使用 bean 时自动发现变量,您必须提供遵循标准命名约定的 getter 和 setter(getVarname、setVarname...)。
无论如何,您希望仅使那些在您的类之外看到业务的变量在外部可见。
Getters and setters are not required in a Java Bean class. All that's required is that the class must be public, it must have a public no argument constructor and it must implement Serializable. However, in order for variables to be discovered automatically when your bean is used you must provide getters and setters following a standard naming convention (getVarname, setVarname...).
In any case, you want to make externally visible only the variables that have a business being seen outside your class.
你的教授是对的。您不想盲目地为所有实例变量创建 getter 和 setter。您想在需要的地方创建它们。
如果您有一个带有
balance
实例变量的BankAccount
类,如果您希望能够检查和设置余额,那么为其创建 getter 和 setter 是有意义的。即使在这里也存在信息隐藏——以封装实现的形式。 getter“
double getBalance()
”可以简单地返回底层实例变量的值(如果它是一个double
),或者它可以返回一个从派生的值。 >BigDecimal
如果这是变量的实现选择,或者它可以调用远程 Web 服务并返回结果。因此,getter/setter 仍然允许实现发生变化,因此不会违反封装性(并且通过扩展,JavaBeans 也不会违反封装性)。JavaBeans 为您所做的就是定义一个接口(
getXXX()、setXXX()
)来获取和设置“属性”,即用户通常想要检查或更改的类的属性。如果您的类具有不被视为“属性”的信息,则无需公开它。例如,假设BankAccount
类有一个用于验证提款的实例变量。如果客户端不需要访问或修改它,则没有必要为其创建 getter 或 setter。Your professor is correct. You do not want to blindly create getters and setters for all instance variables. You want to create them where they are required.
If you have a
BankAccount
class with abalance
instance variable, creating getters and setters for it makes sense if you want to be able to check and set the balance.Even here there is information hiding - in the form of encapsulating the implementation. The getter "
double getBalance()
" could simply return the value of the underlying instance variable if it is adouble
, or it could be returning a value derived from aBigDecimal
if that is the implementation choice for the variable, or it could be calling a remote web service and returning the result. So, the getter/setter still allows for the implementation to vary and thus does not violate encapsulation (and by extension, neither do JavaBeans).What JavaBeans do for you is define an interface (
getXXX(), setXXX()
) for getting and setting "properties", attributes of a class that users would typically want to examine or change. If your class has information that is not considered a "property", there is no need to expose it. For example, let's say theBankAccount
class has an instance variable used for validating withdrawals. If the client does not need access or modify this, there is no point in creating a getter or setter for it.您可能想阅读 为什么 getter 和 setter 方法是邪恶的:
You may want to read Why getter and setter methods are evil:
它通常非常简单,您为需要在外部可见的变量公开 setter/getter,并且不为其他人不知道的变量公开 setter/getters。
It's usually quite simple, you expose setters/getters for the variables you need to make visible externally, and you don't expose setters/getters for variables noone else have any business knowing about.