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.
-
This article blog.berniesumption.com/software/… has great examples to fully understand composition over inheritance.eddy147– eddy14710/15/2015 08:39:51Commented Oct 15, 2015 at 8:39
1 Answer 1
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– Sneh10/10/2015 19:33:54Commented Oct 10, 2015 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.user22815– user2281510/10/2015 19:36:41Commented Oct 10, 2015 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– Sneh10/10/2015 19:39:03Commented Oct 10, 2015 at 19:39
-
I added some links that might help you learn more about composition over inheritance.user22815– user2281510/10/2015 19:44:56Commented Oct 10, 2015 at 19:44