Java 对象之间通过引用进行通信

Java 对象之间通过引用进行通信,java,oop,reference,Java,Oop,Reference,在用Java编写简单的老式Snake时,我终于明白了OOP中最大的难题。这对你来说肯定是微不足道的,但我很长一段时间都无法用语言来表达这个问题 我的问题是关于对象之间的引用。在交流对象时,什么是约定和良好实践?我的意思是,当然不是每一个物体都应该知道它的创造者,例如,但在我的情况下,我觉得没有其他方式可以与它们相互沟通。例如: 我有一个主菜单类,它用一个“新游戏”按钮控制简单的表单。单击按钮时,将创建一个游戏对象(使用其自己的窗体),主菜单窗体设置为不可见,而新游戏对象的窗体设置为可见。当游戏结

在用Java编写简单的老式Snake时,我终于明白了OOP中最大的难题。这对你来说肯定是微不足道的,但我很长一段时间都无法用语言来表达这个问题

我的问题是关于对象之间的引用。在交流对象时,什么是约定和良好实践?我的意思是,当然不是每一个物体都应该知道它的创造者,例如,但在我的情况下,我觉得没有其他方式可以与它们相互沟通。例如:

我有一个主菜单类,它用一个“新游戏”按钮控制简单的表单。单击按钮时,将创建一个游戏对象(使用其自己的窗体),主菜单窗体设置为不可见,而新游戏对象的窗体设置为可见。当游戏结束,我想关闭游戏的形式,使主菜单形式重新出现。但是重新出现发生在游戏对象内部,所以必须有对这个主菜单对象的引用,所以我把它传递给了构造函数,但我觉得不对,因为游戏对象不应该知道主菜单,它们是独立的东西,游戏对象对主菜单唯一感兴趣的是在游戏结束后重新出现,它只是觉得没有足够的理由进行额外的引用

应该怎么做?我认为应该在主菜单类中重新出现,但我如何从那个里跟踪游戏的结束?在专业编程中如何解决此类问题


(对不起我的英语)

你可以创建一个像
GameFinishHandler
这样的界面,让
MainMenu
来实现它。
Game
类在游戏结束时调用所有注册的处理程序

interface GameFinishHandler {
    void doAfterGameFinished();
}

class MainMenu implements GameFinishHandler {
    ...

    private void createGame() {
        this.game = new Game();
        this.game.addHandler(this);
        // ...
    }

    @Override
    public void doAfterGameFinished() {
        game.setVisible(false);
        this.setVisible(true);
    }

class Game {
    private final List<GameFinishHandler> finishHandler = new ArrayList<>();

    public void addHandler(GameFinishHandler handler) {
        finishHandler.add(handler);
    }

    private void afterGameFinished() {
        finishHandler.forEach(GameFinishHandler::doAfterGameFinished);
    }
接口GameFinishHandler{
void doAfterGameFinished();
}
类MainMenu实现GameFinishHandler{
...
私有void createGame(){
this.game=新游戏();
this.game.addHandler(this);
// ...
}
@凌驾
public void doAfterGameFinished(){
game.setVisible(false);
此.setVisible(true);
}
班级游戏{
private final List finishHandler=new ArrayList();
公共void addHandler(GameFinishHandler){
添加(处理程序);
}
私有void afterGameFinished(){
forEach(GameFinishHandler::doAfterGameFinished);
}

所以你的
游戏
类持有你菜单的引用,但它并不“知道”它。它只持有任意数量的finish处理程序。

问题是什么?如果你的程序使用多线程,你可以使用join()。否则,代码将按顺序执行,如果调用新方法,则必须等待它完成。因此,您可以在主菜单中实现所有需要的逻辑。您是对的,我刚刚忘记了join(),因为我的游戏是一个线程,它实际上是最好使用的。这个解决方案也被称为观察者模式吗?我想我几天前已经读过。不,它不是。如果
Game
有一个类似
boolean gameFinished
的字段,你可以观察这个值。这意味着每次
gameFinished
c时都会调用一个更改侦听器由于你的游戏实例,你的游戏类只改变这个值一次,我不会观察这个值。