首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Java中像在C++中一样使用命令模式?

如何在Java中像在C++中一样使用命令模式?
EN

Stack Overflow用户
提问于 2012-02-15 18:59:44
回答 3查看 1.4K关注 0票数 0

最近,我在C++上开发了一个游戏,在这个游戏中,我实现了命令模式来管理键盘输入来控制宇宙飞船。在实例化所有命令时,我会将宇宙飞船指针传递给每个构造函数,以便所有命令都使用相同的宇宙飞船对象。

这种模式在C++中很有意义,因为您可以通过引用传递,但在Java语言中一切都是通过值传递的。如果我试图在Java中实现同样的事情,我如何让每个命令指向相同的对象?

在我所见过的Java中使用的Command模式的所有示例中,每个Command的成员变量是副本还是引用都没有区别。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-15 19:11:59

Java在所有情况下都是通过值传递的,但是所有的“非原始”类型都是以引用的形式存在的,所以对于StringListSpaceship这样的类型,你实际上是在传递一个引用--通过值传递是因为你是通过值传递引用的。这是一种相当混乱的表达方式,我总觉得。

无论如何,它的结果是如果您有一个(大大简化的) Command类

代码语言:javascript
复制
public class Command {
    private Spaceship spaceship;
    public Command(Spaceship ship) {
        spaceship = ship;
    }
}

然后你这样做:

代码语言:javascript
复制
Spaceship ship = new Spaceship();
List<Command> ships = new List<Command>();
for (int i = 0; i < 40; i++) {
    ships.add(new Command(ship));
}

然后,这些Command对象中的每个对象都有一个对同一Spaceship对象的引用。通过值传递引用不会导致引用所指向的Spaceship对象的副本。但是,如果您传递的是ints,那么您确实是在传递副本。

只要记住像int这样的原始类型和像String这样的对象类型之间的区别就可以了。记住,基本类型名称以小写字母开头(并且永远不能由用户定义),而对象类型以大写字母开头,这一点很有帮助。所有用户定义的类型都是对象类型。

票数 2
EN

Stack Overflow用户

发布于 2012-02-15 19:04:05

在java中,他们通过“值”来传递...您传递的是将实现execute方法的真实对象。不同对象之间的共享引用可以通过适当的面向对象设计或公共属性的查找方法注入来实现。命令模式示例取自wikipedia

代码语言:javascript
复制
/*the Command interface*/
public interface Command {
   void execute();
}


/*the Invoker class*/
import java.util.List;
import java.util.ArrayList;

public class Switch {

   private List<Command> history = new ArrayList<Command>();

   public Switch() {
    }

   public void storeAndExecute(Command cmd) {
      this.history.add(cmd); // optional 
      cmd.execute();        
   }

}


/*the Receiver class*/
public class Light {

   public Light() {
   }

   public void turnOn() {
      System.out.println("The light is on");
   }

   public void turnOff() {
      System.out.println("The light is off");
   }

}


/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {

   private Light theLight;

   public FlipUpCommand(Light light) {
      this.theLight = light;
   }

   public void execute(){
      theLight.turnOn();
   }

}


 }
票数 0
EN

Stack Overflow用户

发布于 2012-02-15 19:09:54

因为Java总是通过值传递,所以你需要做一些可变的事情来传递(传递一个可变对象)。

考虑这个例子:

在这种支持按引用传递的不可知语言中

代码语言:javascript
复制
string commandArg = "";
new StringCommand().execute(commandArg);
Console.write(commandArg);

StringCommand.execute(string arg)中,您有arg += "Hello World",那么您的输出将是Hello World

在Java中,只需传递一个StringBuilder,如下所示:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();
new StringCommand().execute(sb);
System.out.println(sb.toString());

其中,StringCommand.execute(StringBuilder sb)包含:

代码语言:javascript
复制
sb.append("Hello World");

StringCommand.execute中通过值传递StringBuilder引用。简而言之,基元类型是通过值传递的,对于对象,对象的引用是通过值传递的。

我希望这能帮到你。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9292079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档