使用带参数的命令模式

4 java oop design-patterns

我有一个像这样的ReloadableWeapon类:

public class ReloadableWeapon {
    //keeping the design really simple, took out weapon logic.
    private int numberofbullets;

    public ReloadableWeapon(int numberofbullets){
        this.numberofbullets = numberofbullets;
    }

    public void attack(){
        numberofbullets--;
    }

    public void reload(int reloadBullets){
        this.numberofbullets += reloadBullets;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下内容interface:

public interface Command {
    void execute();
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Cilent:

    ReloadableWeapon chargeGun = new ReloadableWeapon(10);
    Command reload = new ReloadWeaponCommand(chargeGun,10);
    ReloadWeaponController controlReload = new ReloadWeaponController(reload);
    controlReload.executeCommand();
Run Code Online (Sandbox Code Playgroud)

我想知道,使用命令pattern,我看到的例子,除了命令所作用的对象,没有其他的parameters.

此示例改变execute方法以允许参数.

另一个例子,更接近我在这里,与构造函数中的参数.

在命令中包含参数是不好的做法/代码气味pattern,在这种情况下constructor是子弹的数量?

Loc*_*Loc 8

我不认为在执行中添加参数会是糟糕的设计或违反命令模式.

这完全取决于您希望如何使用Command Object: Singleton或Prototype范围.

如果使用Prototype范围,则可以在Constructor方法中传递命令参数.每个命令实例都有自己的参数.

如果使用Singleton作用域(共享实例),则可以在execute方法中传递命令参数.对于这种情况,命令的单例应该是线程安全的.该解决方案也是IoC/DI框架的朋友.

  • GoF 命令模式不允许将参数传递给“execute”方法。这违背了该模式的目的,因为调用者需要如何调用命令的逻辑,并且命令是不可互换的。Java 的典型命令接口是 [Runnable](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Runnable.html) 和 [Callable](https: //docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/concurrent/Callable.html)。这些 API 不带参数并非偶然。 (2认同)

dou*_*nyy 0

此模式的真正目的是允许定义操作,并稍后执行一次或多次。

您提供的代码是此模式的一个很好的示例:您定义了“重新加载”操作,该操作会收取gun一定量的费用bullets=10

现在,如果您决定修改此代码以添加bullets为参数,那么您完全失去了此模式的目的,因为您每次都必须定义弹药量。

恕我直言,您可以保持代码不变。您必须定义多个ReloadWeaponCommand具有不同值的实例bullets。那么您可能必须使用另一种模式(例如Strategy)在命令之间切换。