使用getter/setter与"告诉,不要问"?

Ska*_*One 30 c++ get set getter-setter

告诉,不问原则,在这里,当我使用的getter和setter方法,人们告诉我,不使用它们往往是贴在我身上.该网站清楚地解释了我应该做什么,不应该做什么,但它并没有真正解释为什么我应该告诉,而不是问.我发现使用getter和setter效率更高,我可以用它们做更多的事情.


想象一下,一类Warrior具有属性healtharmor:

class Warrior {
    unsigned int m_health;
    unsigned int m_armor;
};
Run Code Online (Sandbox Code Playgroud)

现在有人用特殊的攻击攻击我的战士,使他的护甲降低5秒.使用setter's就像这样:

void Attacker::attack(Warrior *target)
{
    target->setHealth(target->getHealth() - m_damage);
    target->setArmor(target->getArmor() - 20);
    // wait 5 seconds
    target->setArmor(target->getArmor() + 20);
}
Run Code Online (Sandbox Code Playgroud)

告诉我们,不要问原则它会是这样的(如果我错了,请纠正我):

void Attacker::attack(Warrior *target)
{
    target->hurt(m_damage);
    target->reduceArmor(20);
    // wait 5 seconds
    target->increaseArmor(20);
}
Run Code Online (Sandbox Code Playgroud)

现在第二个显然看起来更好,但我找不到这个的真正好处.你仍然需要相同数量的方法(increase/ decreasevs set/ get),你会失去询问你是否需要问的好处.例如,你如何将战士的健康状况设定为100?你怎么知道你是否应该使用heal或者hurt,你需要多少健康来治愈或受伤?

此外,我看到世界上一些最优秀的程序员正在使用setter和getter.大多数API使用它,并且它一直在std lib中使用:

for (i = 0; i < vector.size(); i++) {
    my_func(i);
}
// vs.
vector.execForElements(my_func);
Run Code Online (Sandbox Code Playgroud)

如果我必须决定是否相信这里的人们链接我一篇关于告诉,不要求或相信90%的大公司(苹果,微软,机器人,大多数游戏等等)成功的文章赚了很多钱和工作程序,我很难理解为什么会说,不要问一个好的原则.

为什么我应该使用它(我应该吗?)当getter和setter一切看起来更容易时?

Dav*_*eas 32

您仍然需要相同数量的方法(增加/减少与设置/获取)并且您将失去询问是否需要询问的好处.

你理解错了.关键是用一个有意义的操作替换getVariablesetVariable:inflictDamage例如.更换getVariableincreaseVariable只是给你的getter和setter不同的更模糊的名字.

这有什么关系.例如,你不需要提供一个setter/getter来以不同方式跟踪护甲和生命值,inflictDamage类可以通过试图阻止(并在过程中破坏盾牌)然后对角色造成伤害来处理如果盾牌不够或你的算法需要它.同时,您可以在一个地方添加更复杂的逻辑.

例如,添加一个魔法护盾,可以在受到伤害时暂时增加武器造成的伤害.如果你有getter/setter,所有攻击者都需要查看你是否有这样的项目,然后在多个地方应用相同的逻辑,希望得到相同的结果.在告诉方法中,攻击者仍然需要弄清楚他们做了多少伤害,然后告诉你的角色.然后角色可以弄清楚伤害如何在物品上传播,以及它是否以任何其他方式影响角色.

使游戏复杂化并添加火力武器,然后你可以拥有inflictFireDamage(或者将火焰伤害作为该inflictDamage函数的不同参数传递).该Warrior可以找出她是否是由耐火性法术的影响,忽视了火灾损失,而不是在程序中的所有其他对象揣摩他们的动作是如何去影响别人.

  • 这是唯一的补充答案,真正解释了*告诉的好处,不要问*,而不只是说"Duh,它给你更好的封装".你完全应该得到接受,谢谢你的回答!:) (3认同)