我应该在Java中使用全局变量还是传递变量?

3
我正在创建一个基于2D瓷砖的模拟游戏。我有一个2D网格方块数组,可以从许多不同的类和方法中访问和更改它们。是每次传递2D网格方块数组还是将其设为全局变量?哪种做法最好?我在想,创建一个只包含一组变量的类是否可行?所有类都可以继承它吗?这是好主意还是不好的想法?我对Java仍然很新,所以我还在学习很多!谢谢预先。Rel

答案 + 将其用作单例! - Relequestual
5个回答

7

您不应该以数据结构为设计思路。Java是一种面向对象的语言。尝试将问题看作交互的对象。这不是一个二维数组;这是一个Board对象。在问题中构建操作其状态的行为,并隐藏您选择了二维数组的事实。

我还没有完全解决Board的所有细节,但它会像这样开始:

public class Board
{
    // This is what you're passing around now; Board hides it.
    // Square is the abstraction of a position on the Board
    private Square[][] grid;

    public Board(int nRows, int nCols)        
    {
       this.grid = new Square[nRows][];
       for (int i = 0; i < this.grid[i].length; ++i)
       {
           this.grid[i] = new Square[nCols];
       }
    }

    // Now add methods for adding Pieces to the Board, rules for moving them, etc.
} 

有趣。我已经创建了一个名为GirdSquare的类,用于每个正方形。拥有一个GirdSquare的2D数组使我能够更轻松地与路径查找算法交互。 即使我有一个Board对象,我仍然需要访问单个网格正方形,而我想到的最好方法是使用2D数组,就像网格引用一样。 - Relequestual
也许吧,但是一个Board抽象会完全隐藏这个事实。例如,如果我为大富翁写了一个计算机表示,它可能更好地表示为Monopoly属性的LinkedList,因为你总是以那种方式遍历棋盘。在这种情况下,Board抽象仍然很有用;你的二维网格则不需要。 - duffymo
据我理解,我需要将这个类变为单例模式。我正在进行研究,但如果有人找到如何实现这个并使用单例模式的示例,请告诉我。 - Relequestual
最后一句话,对于任何感兴趣的人,这里有一个关于创建单例类的好教程!http://www.javacoffeebreak.com/articles/designpatterns/index.html - Relequestual
Google不鼓励创建单例模式:http://code.google.com/p/google-singleton-detector/ - duffymo
显示剩余2条评论

4

在构造函数中传入它们并将其保存在成员变量中。

如果您从太多地方访问它们,则可能存在设计问题。


请问您所说的"成员变量"是什么意思? 非常抱歉,我还很新于Java和编程。 - Relequestual
这些是每个对象的变量。有时它们也被称为字段。 - starblue
抱歉,我觉得我在这里真的很迟钝。你能给我一个例子吗? - Relequestual
哦,抱歉,我现在明白了。像 int 或 char 一样。与对象 Integer 或 String 相对应。 - Relequestual

2
如果你确定只会有一个“2d网格方块数组”,那么你可以使用单例模式,将其变为全局变量。但是,对于这种方法有赞成和反对的观点。可能有一天你想要预加载地图,但是单例会妨碍这一点(无法创建单例的第二个实例)。

嗯,我可能最终会扩展它以拥有多层。我猜那种方式对于这种情况不是最好的。 - Relequestual
即使你有多个楼层(从2D到3D),仍然只有一个全局游戏状态。因此单例仍然可用。 - KarstenF
确实。我得研究一下单例模式以及如何使用它们。我之前没有接触过或者被教过这个。再次感谢。 - Relequestual
有没有人能给我推荐一个好的单例模式教程? - Relequestual
Google 会劝阻您创建单例模式:http://code.google.com/p/google-singleton-detector/ - duffymo

1

如果你确实需要,在包含网格的类(A)中将网格声明为公共的,然后静态导入A类(import static A;)。这将使您能够与网格交互而无需扩展A类,至少是这样。

您的代码不应从太多地方访问网格。考虑重构您的代码以避免必须从各个地方操作网格。分离您的关注点。并且像您提到的那样使用继承绝对不是一个好主意。


1
我建议将其设置为静态,但创建一个明确的类来从中读取数据,比如GridSquaresAcessor。在这个类中,您可以编写所有访问数组的方法。更好的做法是将其作为此类的私有静态字段,以避免任何其他代码以未在此类中定义的方式进行操作。
在每个需要访问该数组的类中,您可以将一个GridSquaresAcessor作为构造函数的参数传递,并将其存储在本地变量中。
我个人不喜欢单例模式,因为它们使测试代码非常困难...
如果您的代码是多线程的,请确保将2D数组同步。

那差不多是我的想法,只不过你表达得更好。 还有其他人认为这是一个好的做法吗? - Relequestual

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接