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



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

我将此功能委托给如下所示的类。我想实现这一点,以便在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;
    }
}

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

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

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

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

首先,这些名字几乎完全无关——以某种方式与它们有关。

SQUARE_DATA_STORE
SQUARE_DATA_REGEX

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

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

如果你的代码是如此不言自明,以至于读者无法通过你的注释和代码弄清楚这两个字段是相关的,那么就出了可怕的错误。我很难想象这段代码是如此复杂,以至于它们的关系无法轻易沟通。


更新后编辑

答案仍然是否定的。

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

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

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

IMO 你过度思考,高估感知的复杂性:除了可能对于模板解决方案,IMO 可能过度设计难度级别,你最好写一两个句子,这应该足以关联加载和保存格式的"字段"。

代码中放置注释,以解释它们是相关的,它们是如何相关的,它们的用途,如果一个被更改,另一个应该相应地修改。

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

确保生成和发布过程运行单元测试,如果其中一个未通过,则失败。

最新更新