0

我正在制作一个小型棋盘游戏程序,它需要将棋盘的状态保存到文件中,然后从文件中读取并重新创建棋盘。

我将此功能委托给下面显示的类。我想实现这一点,以便在 SQUARE_FORMAT 常量中捕获棋盘正方形的保存格式及其坐标,并在 LOAD_REGEX 常量中捕获用于读取相同信息的正则表达式。两者都应该在代码中相互关联,并且能够在视觉上破译(我的意思是一个人应该能够清楚地看到它们与相同的数据相互关联)

在 Java 代码中是否有这样的习惯用法或模式?

public class BoardPersistenceUtility {

    private final String SQUARE_SAVE_FORMAT = "";
    private fial String LOAD_REGEX = "";

    public void save(PrintWriter writer, Board board) {

    }

    public Board load(BufferedReader reader) {
        // Implement
        return null;
    }
}

更新1:

再次阅读我的问题时,我想这可能有点令人困惑,关于我到底在寻找什么。我正在特别寻找表示 SQUARE_SAVE_FORMAT 的正确方法,以便它与正则表达式 LOAD_REGEX 明确相关。

SQUARE_SAVE_FORMAT 理想情况下是一个使用特殊字符/变量的字符串,这些特殊字符/变量将被实际值替换,结果将保存到文件中。LOAD_REGEX 是将用于从文件中读取内容的相应正则表达式。正则表达式将使用捕获组,因此我可以根据从捕获组获得的值重新创建原始对象。

我的问题是,围绕创建这样的字符串对的习语是什么——其中一个是用于保存数据的格式字符串,另一个是在读取该数据时使用的正则表达式。

更新 2:

再想一想,我想我已经能够更好地澄清我的问题了。

如果您查看这两个字符串,SQUARE_SAVE_FORMAT 是一个格式字符串,将在 String.format() 中用于为板上的正方形创建文本,并将其保存在文件中。常量 SQUARE_LOAD_REGEX 是一个正则表达式,用于读取行并将相关部分捕获到命名组中,因此我可以重新创建原始对象。(对不起,如果我的正则表达式稍微不正确......我很快写了一些东西,但我需要刷新一些正则表达式原则以确保这确实是我需要的)

如果你从视觉上看这两个字符串,很难将它们关联在一起。也许是因为我们没有任何 Java 格式字符串中的命名变量。我们能做的最好的事情是指定 %i ,其中 i 是参数的索引。

我想了解是否有任何成语或模式来表示这样的字符串对,其中一个用于将某些数据格式化为文本,另一个用于读取相同的文本并解析它的部分。

public class BoardPersistenceUtility {

    private final String SQUARE_SAVE_FORMAT = 
                  "%d,%d:%b-%s";
    private final String SQUARE_LOAD_REGEX = 
                  "^(?<row>\d*),(?<col>\d*):(?<mine>true|false)-(?<status>\w)$";

    public void save(PrintWriter writer, Board board) {

    }

    public Board load(BufferedReader reader) {
        // Implement
        return null;
    }
}
4

3 回答 3

2

注意:你调用SQUARE_SAVE_FORMATLOAD_REGEX它们不是“常量”,因为你没有声明它们static final。最好保持术语清晰:-)

链接这两者的最简单方法是定义一个将两者都包含为(最终)字段的类。如果您计划定义多个这样的信息对,您可以定义该类的多个实例,每个实例对应一种格式。

如果您真的想将它们保留为常量,最好将封闭类定义为enum. 请注意,Javaenum也可能包含方法,因此您可以选择在枚举实例本身中将保存/加载逻辑实现为策略,并以多态方式调用它们,这可能有助于简化代码。

于 2012-05-30T10:21:52.890 回答
1

在您的代码中添加注释以说明它们是相关的、它们是如何相关的、它们的用途,以及如果一个被更改,另一个应该相应地修改。

实施单元测试以确保可以加载保存的板。

确保您的构建和发布过程运行单元测试,并且如果其中一个未通过则失败。

于 2012-05-30T10:22:16.590 回答
1

我仍然不确定你的意思,但需要格式化,所以回答而不是评论。

首先,这些名字几乎是完全不相关的——以某种方式与它们相关。

SQUARE_DATA_STORE
SQUARE_DATA_REGEX

其次,如果只有一种格式,那么区分已保存数据的“样式”是没有意义的——如果有BoardPersistenceUtility多种格式,那么该信息将被捕获在持久性实用程序子类中,例如SquareFormatPersister或其他东西。

第三,根据您的文本,一个字符串是实际存储数据的位置。另一个是正则表达式。在这种情况下,两者永远不会“视觉上相似”——任何复杂的正则表达式永远不会(非常)看起来像它们可以表示的字符串。(在这种情况下,我们没有任何线索,因为我们当然不知道棋盘数据会是什么样子。)

如果您的代码如此不言自明,以至于读者无法通过您的注释和您的代码找出这两个字段是相关的,那么就出现了可怕的错误。我很难想象这段代码如此复杂,以至于他们的关系无法简单地传达。


更新后编辑

答案仍然是否定的。

您可以使用模板机制为字段提供名称,类似于您的正则表达式中使用的名称。这也可能使代码更加不言自明,因为您将使用命名值(如“row”或“col”)填充模板上下文。

您可以使用真正的解析器/生成器,但是那里的复杂性有点太多了。

您可以使用 DSL(内部使用 Groovy、JRuby、JavaScript 等或外部,这使我们回到解析)并以这种方式编写代码块。

IMO 你想多了,并且高估了感知的复杂性:除了模板解决方案,IMO可能会过度设计难度,你最好写一两个句子,这应该足以关联加载和保存格式的“字段”。

于 2012-05-30T10:55:04.773 回答