2

I have recently started reading Heads First Design Pattern Book as well as coding on my final year project. In my project I am having Tanks which extends Entity. A Entity can be anything in the game which is positionable on the game map. Entity is an abstract class.

I have a move() method in my Entity class which will be used to change the position of tank. I will have a lot of different kinds of tank in my game and they will move faster or slower according to the velocity they have. Now my question is, I read about strategy pattern and according to it I should use interface for movement as I don't want to keep overriding or changing move method behaviour every time in different tanks. Maybe if a tank doesn't move I need to keep the move method empty.

So should I rather than hard-coding move() method in every Tank introduce a Movable interface in Tank class? This will be beneficial as I can change tank's movement behaviour during runtime but then I am also not sure how to do it as I may have to then introduce x and y location of tank inside the interface implementations somehow and change them accordingly. This will defeat purpose of Entity class as Entity class is used to hold x and y locations.

Please suggest me the correct way to do it.

Let me know if question is not clear because it is a bit hard to express my question as it's a bit complex.

Sneh
  • 157
  • 6
  • This article http://blog.berniesumption.com/software/inheritance-is-evil-and-must-be-destroyed/ has great examples to fully understand composition over inheritance. – eddy147 Oct 15 '15 at 08:39

1 Answers1

2

What I recommend is keeping all of your behavior in the tank, but keep the parameters such as velocity in another object. It would look something like this, in pseudocode:

interface TankParameters {
  int getVelocity();
  int getArmor();
  int getAttackPower();
}

class Tank : Entity {
  private TankParameters parameters;
  private Point location;

  public Tank(TankParameters p) {
    parameters = p;
  }

  public void move(Direction d) {
    // Use the direction, velocity on the parameters object,
    // something else like time and calculate the new location.
  }
}

You can have a single Tank class but alter the behavior of each Tank object by passing in different parameters at construction time.

This is a form of Dependency Injection: while the TankParameters class is not technically a dependency because it is contrived and exists solely to break up the responsibilities of the Tank class, the idea of passing in arbitrary objects to alter behavior is a cornerstone of DI.

This is not quite a strategy, simply because TankParameters does not actually contain any algorithms. It exists to externalize data not behavior.


While not strictly part of your question, I would also change Entity to be an interface and use composition instead of inheritance. The links below go into more detail about the benefits of using this approach.

See Also

  • If I do this then what is the use of entity class? Because I currently store my x and y locations in entity as well as the angle. Should I just get rid of entity class then? I mean there can be other things I can store in Entity class like I will be storing databaseId etc but I can then directly store them somewhere else then. Just a bit confused here. – Sneh Oct 10 '15 at 19:33
  • I was answering specifically on Tank, not Entity. But in the big picture I would prefer to turn Entity into an interface and use composition over inheritance. –  Oct 10 '15 at 19:36
  • Thanks for the prompt reply. I will accept your answer and read more about composition and try to use it in my game. – Sneh Oct 10 '15 at 19:39
  • I added some links that might help you learn more about composition over inheritance. –  Oct 10 '15 at 19:44