Tell,请问原则 - 我应该在这里申请吗?

时间:2012-03-07 22:17:21

标签: design-patterns

假设我有某种图形动画代码,我有两个类: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但是违反了告诉 - 请求 - 原则吗?

2 个答案:

答案 0 :(得分:6)

为什么动画师需要关心?鉴于当前逻辑,锁定检查应在Sprite.move()方法内完成。动画师唯一的责任就是告诉精灵移动。由精灵来决定它是否移动。

答案 1 :(得分:4)

基于这个原则,看起来第二种选择是可行的方式。

  

告诉对象你想要什么。让它弄清楚如何做到这一点。

不要过分担心函数的名称,更好的是,如果您害怕不记得该函数的工作方式,只需正确评论函数,以便您或其他人可以轻松维护。