Search code examples
javaoopdesign-patterns

Using the Command Pattern with Parameters


I have a ReloadableWeapon class like this:

public class ReloadableWeapon {

    private int numberofbullets;
    
    public ReloadableWeapon(int numberofbullets){
        this.numberofbullets = numberofbullets;
    }
    
    public void attack(){
        numberofbullets--;
    }
    
    public void reload(int reloadBullets){
        this.numberofbullets += reloadBullets;
    }
}

with the following interface:

public interface Command {
    void execute();
}

and use it like so:

public class ReloadWeaponCommand implements Command {

    private int reloadBullets;
    private ReloadableWeapon weapon;
    
    // Is is okay to specify the number of bullets?
    public ReloadWeaponCommand(ReloadableWeapon weapon, int bullets){
        this.weapon = weapon;
        this.reloadBullets = bullets;
    }
    
    @Override
    public void execute() {
        weapon.reload(reloadBullets);
    }
}

Client:

ReloadableWeapon chargeGun = new ReloadableWeapon(10);
Command reload = new ReloadWeaponCommand(chargeGun,10);
ReloadWeaponController controlReload = new  ReloadWeaponController(reload);
controlReload.executeCommand();

I was wondering, with the command pattern, with the examples I've seen, other than the object that the command is acting on, there are no other parameters.

This example, alters the execute method to allow for a parameter.

Another example, more close to what I have here, with parameters in the constructor.

Is it bad practice/code smell to include parameters in the command pattern, in this case the constructor with the number of bullets?


Solution

  • The very purpose of this pattern is to allow to define actions, and to execute them later, once or several times.

    The code you provide is a good example of this pattern : you define the action "reload", that charges the gun with an amount of bullets=10 ammunition.

    Now, if you decide to modify this code to add bullets as a parameter, then you completely lose the purpose of this pattern, because you will have to define the amount of ammunition every time.

    IMHO, you can keep your code as it is. You will have to define several ReloadWeaponCommand instances, with different value of bullets. Then you may have to use another pattern (such as Strategy) to switch between the commands.