• Advertisement

Java Using the Strategy Pattern to avoid downcasting

Recommended Posts

I was reading on this site about the Liskov substitution principle. It states:


As per the LSP, functions that use references to base classes must be able to use objects of the derived class without knowing it. In simple words, derived classes must be substitutable for the base class.

From my understanding this means that whatever methods are in my base class, they must be implemented in my subclass, and according to this page, if you override a method in the base class and it does nothing or throws an exception, you're in violation of the principle.

Suppose I had an abstract class called Weapon, and the subclasses ReloadableWeapon and Sword. ReloadableWeapon contains a method that's unique to that class, called Reload(). When declaring objects, standard practice is you do it from the abstract class and then subclass, like so:

Weapon rifle = new ReloadableWeapon(); 
Weapon sword = new Sword();

If I wanted to use the reload method for a rifle, I could cast it. Based on numerous articles and textbooks, this could lead to problems later on.

Also, if I have the reload method in the base class Weapon, then Sword would ignore or throw, which is wrong.

If I wanted to avoid all that, would using the Strategy Pattern be a viable option?

public final Weapon{

    private final String name;
    private final int damage;
    private final List<AttackStrategy> validactions;
    private final List<Actions> standardActions;

    private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks)
        this.name = name;
        this.damage = damage;
        standardActions = new ArrayList<Actions>(standardActions);
        validAttacks = new ArrayList<AttackStrategy>(validActions);

    public int attack(String action){} // - Call any actions that are attacks.

    public void standardAction(String action){} // - Call aim or reload here.
    public static Weapon Sword(final String name, final damage, final List<AttackStrategy> standardActions, final List<Actions> attacks){
        return new Weapon(name, damage, standardActions, attacks);

Attack Interface and Implementation:

public interface AttackStrategy{ 
  void attack(Enemy enemy); 

public class Shoot implements AttackStrategy { 
  public void attack(Enemy enemy){ 
    //code to shoot 
public class Strike implements AttackStrategy { 
  public void attack(Enemy enemy){
    //code to strike 

'm not asking if I've implemented the Strategy Pattern correctly, but rather can I use the pattern when faced with a subclass that has a method unique to that subclass and I don't want to cast it? or in other words, rather than violate the LSP, can I prohibit the use of inheritance and use the Strategy Pattern to implement the require methods?

The pattern solves my problem in 2 ways:

  • I don't have to downcast, I can store my Weapons in a List<Weapon> collection without worrying about checking the type, and then casting
  • Any weapon that isn't Reloadable, won't have the concrete class Reload. This mean no throwing or leaving the method blank


Edited by SvetlanaRosemond

Share this post

Link to post
Share on other sites

It sounds like you still have a ReloadableWeapon class.  My question to you is, if you're baking behavior into strategies, why do you still have a ReloadableWeapon class?  Presumably your weapon's AttackStrategy can deal with ammo management.  That way you make downcasting not a problem by not having anything to downcast to.

It's common for weapon code to go a step further and abstract even further than strategies (to the point of data-driving everything), but you're thinking on the right track.

Edited by SeraphLance

Share this post

Link to post
Share on other sites

I think your basic premise of Sword and Rifle belonging in the same class hierarchy is wrong, or your Sword definition is wrong, or your Weapon definition is wrong.

The simple solution is to unify how a sword and a rifle work, by adding a Reload method to the Sword. It's a silly thing in terms of reality, but we're not interested in reality modeling, we're writing a game. This unifies both weapons, and your entire problem disappears like snow in the sun.

The second option is to acknowledge they're different weapons. The game character does something different with a Rifle. The simple solution is then to make them truly different things, each in their own hierarchy. This is not different from not having Money in the same class hierarchy, even though it could be used as a weapon (bar of gold dropped from a 10 story building can severely damage you!).

Your Strategy acknowledges the weapons are different, and then you add another layer of software that hides the difference. You make new instances of the strategy class that basically encodes how to handle each type of weapon, inside the weapon itself.

In other words, your current notion of Weapon is flawed, and to correct it, you add a wrapper layer around it to unify the interface?


Is that not equivalent to unifying to a new weapon class that just has a "useIt" method and nothing else? The Reload becomes a hidden implementation detail. Wouldn't it be simpler to just ditch the Strategy, and make a simpler Weapon definition where you directly encode the weapon behavior, where Reload could be a private sub-function of Rifle.


Share this post

Link to post
Share on other sites

IMO the strategy pattern is not exactly the way to go, because we do not have a one-time configuration problem here. Instead, items (where weapons count to) in game have several usages from which the player or AI selects one at a time and another at a later time. E.g. striking with a rifle or sticking with a bayonet or emitting lightning bolts from a sword or shooting bullets as well as grenades with the same weapon ... Hence the amount of charges (as generalization of ammo) is not exactly part of the class Item but belongs to the particular action you want to be able to do with the Item.

So let us assume that there is a class ActionObjectA that (when an instance is attached) defines that the item can be used as an object of some actions (in the grammatical sense). The ActionObjectA class has some properties that are meaningful with respect to that set of actions, so that those actions can be selected if and only if that ActionObjectA is attached. Additionally, stuff like adding the set of actions for selection only if the item is hold in hand can be added simply.

Example: Let ActionObjectA be BulletFirearm with properties for the current amount of bullets and the reload amount of bullets. The actions belonging to it may be "shoot bullet" and "reload bullets". When the player controller / AI selects the "shoot bullet" action, the action dispatcher invokes the action class asking whether execution of the action is actually possible just now. The action looks at the properties and returns "true" if at least one bullet is loaded. Hence the action will be invoked to execute.

Notice that there is a collection of dump data (the ActionObjectA, ActionObjectB, ...) and belonging but separated active components (the actions). Notice further that the meaning of the item is defined by which ActionObject* instances are added, perhaps even at runtime (e.g. weapon modifications).

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement