假设我有某种图形动画代码,我有两个类:Sprite和SpriteAnimator。 SpriteAnimator负责定期移动精灵。 Sprite有一个属性可以阻止它移动。
我首先实现了这样的用例:
public class Sprite
{
public bool Locked;
public void MoveTo(int x, int y){}
}
public class SpriteAnimator
{
private List<Sprite> Sprites;
public void DoMovement()
{
foreach (Sprite sprite in Sprites)
{
if (!sprite.Locked) MoveTo(newX, newY);
}
}
}
......但后来我记得Tell-don't ask principle,我觉得我在询问国家,做出决定,然后告诉他们该做什么 - 就像原则禁止我一样。所以我重新编写:
public class Sprite
{
private bool Locked;
public void MoveIfNotLockedTo(int x, int y) { ... }
}
public class SpriteAnimator
{
private List<Sprite> Sprites;
public void DoMovement()
{
foreach (Sprite sprite in Sprites)
{
MoveIfNotLockedTo(newX, newY);
}
}
}
..但这实际上是更好的代码吗?我不确定我对包含“If”这个词的方法名称感觉如何。
还有第三种选择 - 控制器获得精灵锁定状态的所有权。像这样:
public class Sprite
{
public void Move(int x, int y) { ... }
}
public class SpriteAnimator
{
private List<Sprite> Sprites;
private List<Sprite> LockedSprites;
public void DoMovement()
{
foreach (Sprite sprite in Sprites)
{
if (!LockedSprites.Contains(sprite) MoveTo(newX, newY);
}
}
}
...但是当我得到O(N ^ 2)循环时,这会对性能产生影响。
那你们觉得怎么样?是时候务实了,选择我认为最好的选项#1但是违反了告诉 - 请求 - 原则吗?
答案 0 :(得分:6)
为什么动画师需要关心?鉴于当前逻辑,锁定检查应在Sprite.move()
方法内完成。动画师唯一的责任就是告诉精灵移动。由精灵来决定它是否移动。
答案 1 :(得分:4)
基于这个原则,看起来第二种选择是可行的方式。
告诉对象你想要什么。让它弄清楚如何做到这一点。
不要过分担心函数的名称,更好的是,如果您害怕不记得该函数的工作方式,只需正确评论函数,以便您或其他人可以轻松维护。