如何确保保存和解析对象的字符串表示的格式正确关联

时间:2012-05-30 10:16:20

标签: java regex format

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

我将此功能委托给下面显示的类。我想实现这一点,以便在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格式的String中没有任何命名变量。我们能做的最好的事情是指定%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;
    }
}

3 个答案:

答案 0 :(得分:2)

注意:您调用SQUARE_SAVE_FORMATLOAD_REGEX“常量”,因为您尚未声明它们static final。最好保持术语清晰: - )

将这两者联系起来的最简单方法是定义一个包含两个(最终)字段的类。如果您计划定义多个此类信息对,则可以定义该类的多个实例,每种类型的格式一个。

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

答案 1 :(得分:1)

在您的代码中添加注释,以解释它们是否相关,它们如何相关,它们用于什么,以及如果更改了一个,则应相应地修改另一个。

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

确保构建和发布过程运行单元测试,如果其中一个没有通过则失败。

答案 2 :(得分:1)

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

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

SQUARE_DATA_STORE
SQUARE_DATA_REGEX

其次,如果只有一个BoardPersistenceUtility,则区分已保存数据的“样式”是没有意义的 - 如果有多种格式,那么该信息将在持久性实用程序子类中捕获,如{{ 1}}或者什么。

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

如果您的代码非常不言自明,以至于读者无法通过您的评论和您的代码弄清楚这两个字段是相关的,那么就会出现严重错误。我很难想象这段代码非常复杂,以至于他们的关系无法轻易传达。


更新后修改

答案仍然没有。

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

你可以使用一个真正的解析器/生成器,但复杂性太多了。

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

IMO你过度思考,并高估了感知的复杂性:除了可能的模板解决方案,IMO可能会为难度级别过度工程,你会很远最好写一两句话,这应该足以与加载和保存格式的“字段”联系起来。