【问题标题】:How would a separate GUI class communicate with logic classes?单独的 GUI 类如何与逻辑类通信?
【发布时间】:2014-06-12 15:34:29
【问题描述】:

我正在尝试设计一个具有多个类的井字游戏。一个类是 GUI 类,它显示 9 个按钮来表示井字游戏的 9 个区域。另一个类是我设置游戏的驱动程序类。其他类是游戏背后的逻辑(棋盘、移动)。但是,我不确定如何让 GUI 类和逻辑类相互交互。

我不希望 GUI 类直接访问板,但我不知道我应该如何来回传递信息。例如,如果我点击一个按钮,按钮的文本应该更新以反映标记(X 或 O),但我不知道将文本更改为哪个标记,而不检查轮到谁了信息位于 Board 类中。按下按钮还应该让董事会知道有哪些可用空间以及已经进行了玩家回合。

我试图让 Board 类具有访问器方法,以便 GUI 可以弄清楚如何正确更新自身,但我完全不知道如何在 GUI 类中调用这些方法。

【问题讨论】:

    标签: java user-interface model-view-controller


    【解决方案1】:

    我认为您误解了 Model-View-Controller 背后的概念。在某些时候,组件将不得不相互交互,因为它们必须在它们之间传递信息。关键是将交互与结果的实现分离

    换句话说,视图应该有一些标准接口,让模型/控制器通知它需要更新,模型/控制器应该有一些标准接口,视图用来通知用户输入,但也不应该关心对方如何处理这些事件。从理论上讲,一个完美的 MVC 实现可以让您切换任何一个组件以实现完全不同的实现,只要它坚持相同的接口并且一切都可以完全按预期工作。

    在你的情况下,我会设计这样一个游戏引擎类,它具有这样的方法:

    int makeMove(row, column)
    

    其中rowcolumn 是棋盘上的坐标,返回的int 代表玩家(X = 0,O = 1 或类似值。您甚至可以使用enum 更明确` `) 轮到谁了,这样 GUI 就可以用该玩家的图标更新相应的方块。

    然后游戏引擎会期望视图至少具有以下两种方法:

    void setPlayerTurn(int player)
    

    这告诉 GUI 它应该更新轮到它的显示器(与上面相同的player

    void setPlayerWon(int player, rows, columns)
    

    这告诉 GUI 一个玩家获胜,并且它应该更新标识为 rowscolumns 的三个方格作为让玩家获胜的方格,player 是相同的玩家编号以便它可以显示适当的状态消息。

    游戏逻辑,包括跟踪棋盘的状态以及轮到谁,都可以独立包含在游戏类中,GUI 所做的只是将信息从用户传递到游戏,再从游戏传递给用户。从理论上讲,您可以使用完全不同的实现替换任何一个组件,该实现遵循这些接口,并且仍然可以按预期进行游戏。

    因此,GUI(视图)最终会引用游戏逻辑(模型),反之亦然。但它们只是通过一个非常狭窄和通用的接口相互交互。双方都不知道也不关心对方如何处理通过该接口传递的信息。

    请注意,在这个简化的示例中,我将控制器与视图结合在一起,这在您设计单一用途的 GUI 时是很常见的事情。从本质上讲,GUI 的设计使其只能用作井字游戏板,但它希望您提供自己的一套规则(模型)。

    话虽如此,您可以看到,通过让 GUI 简单地公开允许您设置网格上任意正方形的状态(文本和图标)的方法,进一步解耦这些并不需要更多的时间,并且显示状态消息。它期望得到一个控制器,该控制器提供一种方法来通知用户与网格上的哪个方块进行交互。然后,控制器将提供胶水来连接通用“带有状态消息的网格”视图和游戏逻辑模型之间的接口,该模型需要我上面描述的接口。

    在这种情况下,GUI(视图)获得对控制器的引用,反之亦然,然后控制器获得对游戏逻辑(模型)的引用,反之亦然。

    【讨论】:

    • 谢谢!这当然很有意义。
    【解决方案2】:

    您可以将它们设为静态字段并通过 ClassType.getVariable() 访问它们

    例如:

    public class Board
    {
        private static char currentPlayer = 'X';
    
        public static char getCurrentPlayer()
        {
            return currentPlayer;
        }
    }
    

    在你的 GUI 类中你使用Board.getCurrentPlayer();

    【讨论】:

      【解决方案3】:

      您可以导入逻辑类,然后在 GUI 中创建该类的实例,然后您就可以访问该类中的所有方法。

      它看起来像这样的代码

      import Logicclassname
      public guiclass{
      Logicclassname logic=new logicclassname();
      }
      
      public void updatefield(){
      logic.functiontoexecute();
      /* rest of code*/
      }
      

      【讨论】:

      • 我试图避免让我的 GUI 类具有 Board 类的实例。我想如果我这样做,那么 GUI 并没有真正与逻辑分开。我的老师的措辞是这样的:“请注意,GUI 需要保持其显示与当前板位置保持同步,但您不希望板本身成为 GUI 的一部分。您可以做什么确保板子提供的方法允许 GUI 查询板子以获取更新显示所需的信息。”
      • 据我所知,如果没有实例,您将无法访问这些方法,但如果您只希望董事会能够访问它实际需要的方法,请将其设为公开,其余设为私有。
      • 老师的措辞让我相信我的 GUI 不应该有 Board 类的实例,但感谢您的帮助。
      猜你喜欢
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2013-07-05
      • 2012-08-11
      相关资源
      最近更新 更多