【发布时间】:2010-10-20 14:33:21
【问题描述】:
假设我的任务是编写某种 RPG。这意味着,例如,我要跟踪 CharacterGameCharacter 及其统计信息,例如智力、伤害加成或生命值。
我非常害怕在项目结束时我可能最终会处理大量字段 - 对于每个字段,我都必须确保它们遵循一组非常相似的约束和行为(对于例如,我希望它们介于最小值和最大值之间;我希望能够区分“基本值”和“临时奖金”;我希望能够在不通过设置器的情况下增加和减少两者和吸气剂)。突然之间,对于每个字段,我都需要一个(两个?)getter 和四个 setter,也许还需要几个重置器!即使对于 10 个字段,这也意味着很多方法都相似,eek。
对于 DRYness,我已经开始在 Field 类中封装处理这些统计数据的逻辑,以便我可以编写诸如 intelligence.applyBonus(10) 或 hitpoints.get() 之类的代码(注意返回的值在范围内)等. 我什至花了这么多时间来创建类来将这些字段组合在一起,但这不是现在的重点。
现在,我在将Field“插入”GameCharacter 时遇到了这个问题:大多数 Java 教科书都说每个类都应该有带有公共 getter 和 setter 的私有字段。这在理论上听起来不错,而且我已经围绕int 建立了一个完整的课程;但是,当您发现自己调用 getter 来获取... getter 时,这个想法听起来并不可靠:
thisCharacter.getIntelligence().get() //eeek
我更愿意直接访问该字段。也许这是我的 Python/VB [1]“背景”,但对我来说它更干净、更清晰、更直接:
thisCharacter.intelligence.get()
公共领域的(理论上)问题是我放弃了对它的所有控制;例如,在代码库中的某个其他点,不幸的是,可能会发生以下情况:
thisCharacter.intelligence = somethingThatReallyIsNull;
听起来像是一个微妙的错误......但是......我的意思是,我真的应该担心吗?我从来没有打算直接分配Field [2],我在 Javadoc 中记录了这不是应该做的事情,但我仍然是新来的,所以我有点被撕裂了。
所以我想听听您对这个话题的看法。封装的优势是否如此巨大,以至于我应该继续使用 getter getter 和 setter getter 等等......还是我应该采取健康措施进行封装并将 Field 保留为 public 字段?
[1] 是的,我知道。我一直在努力忘记。但是我们最近也看到了一些 C# 和 man,它们的属性并不甜。哦,好吧。
[2] 构造函数除外!并且 getter 不会将我从错误的构造函数中拯救出来。
【问题讨论】:
-
“使用公共字段是我放弃了对它的所有控制” - 当然,但是
public final字段,没有什么可以出错的。当你的字段是一个包装的 int 时,它应该是final,否则你有两种设置方式:thisCharacter.getIntelligence().set(7)和someIntelligence.set(7); thisCharacter.getIntelligence(someIntelligence)。
标签: java encapsulation getter