Lets say I have some sort of graphical animation code where I have two classes: Sprite and SpriteAnimator. The SpriteAnimator is responsible for moving the sprites at regular intervals. The Sprite has a property which can lock it from movement though.
I first implemented this use case like this:
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);
}
}
}
…but then I remembered Tell-don’t ask principle, and I feel I’m asking about the state, making a decision and then tell them what to do – just like the principle forbids me. So I recode to this:
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);
}
}
}
..but is this actually better code? I’m not sure how I feel about method names containg the word “If”.
There is also a third option – where the Controller takes ownership of the locked-states of the sprites. Something like this:
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);
}
}
}
…but this has a performance impact as I get O(N^2) loop.
So what do you guys think? Is it time to be pragmatic and choose option #1 which I feel is the best but violates the tell-don’t-ask-principle?
Based on the principle, it looks like the second option is the way to go.
Don’t worry too much about the function’s name, better yet, if you’re afraid of not remembering how that function works, just comment the function properly so it would be easily maintainable by you, or someone else.