如何在不损害java+PDFBox中DRY原则的情况下格式化代码



请原谅这个问题的模糊性,让我解释一下自己。

我使用PDFBox创建了一个PDFGenerator。PDF大约有9页,实际的PDFGenerator.java是一个拥有近4k行代码的怪物,其中很大一部分代码是PDF中文本的恒定像素定位。

当前版本(v1)包括两个主要变量,一个供应变量和一个排气变量。所以每一行都有一个供给值和一个排出值。

整个过程非常完美,我对整个生成过程非常满意。然而,现在v2已经到来,客户希望能够创建供应或排气,或者两者都

这就是DRY原理的问题所在。理论上,两者的代码都已经存在。当它是这样或那样时,唯一会改变的是文本的位置,现在它位于两列之间的中心。

示例:两者(当前正在生成)

属性。。。。。。。。。。。。。供给废气

高度。。。。。。。。。。。。。。。。。。。。。。。。。。5………….5

宽度。。。。。。。。。。。。。。。。。。。。。。。。。。。5………….5

示例:一个或另一个

属性。。。。。。。。。。。。。。。。。。。。。。。。供应

高度。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5…………

宽度。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5…………

这是一个生成一行的块:

pdContentStream.beginText();
pdContentStream.setFont(boldFont, BOLD_FONT_SIZE);
pdContentStream.newLineAtOffset(TEXT_BEGIN, currentYCoord);
pdContentStream.showText(messageSource.getMessage("pdf.value.TDVentilator", null, this.locale));
pdContentStream.endText();
pdContentStream.beginText();
pdContentStream.setFont(boldFont, BOLD_FONT_SIZE);
pdContentStream.newLineAtOffset(SUPPLY_BEGIN, currentYCoord);
pdContentStream.showText(messageSource.getMessage("pdf.supply", null, this.locale));
pdContentStream.endText();
pdContentStream.beginText();
pdContentStream.setFont(boldFont, BOLD_FONT_SIZE);
pdContentStream.newLineAtOffset(EXHAUST_BEGIN, currentYCoord);
pdContentStream.showText(messageSource.getMessage("pdf.exhaust", null, this.locale));
pdContentStream.endText();

请记住,这些类型的块在整个生成过程中重复出现。现在是我的DRY问题出现的地方。

我想到的第一件事是将当前代码导出到一个仅用于生成两者的函数中,并创建(复制/粘贴)第二个用于其中一个的函数。但是,代码的很大一部分会重复这样做(由于我们只有一个输出变量,而没有两个,所以减少了一个块)。

我可以想到的另一种方法是在每个代码块之前创建一个if(),如果这种情况,那么就取那个块,如果那种情况,则取那个块。再一次,DRYness不存在(因为同样的if必须出现在每个代码块之前)。

我的问题是:一般来说,最好的方法是什么?我不介意这个怪物是否会从4k行代码再次增长到8k行代码,但如果有更简单(更好)的方法,我会洗耳恭听。

干杯:)

查看您的代码:

pdContentStream.beginText();
pdContentStream.setFont(boldFont, BOLD_FONT_SIZE);
pdContentStream.newLineAtOffset(EXHAUST_BEGIN, currentYCoord);
pdContentStream.showText(messageSource.getMessage("pdf.exhaust", null, this.locale));
pdContentStream.endText();

我认为唯一不同的部分是给messageSource.getMessage()的第一个参数。

因此,您的重构可能会从引入开始

public void prepareContent(Whatever pdContentStream, String message) {
pdContentStream.beginText();
pdContentStream.setFont(boldFont, BOLD_FONT_SIZE);
pdContentStream.newLineAtOffset(EXHAUST_BEGIN, currentYCoord);
pdContentStream.showText(messageSource.getMessage(message, null, this.locale));
pdContentStream.endText();
}

然后你的主要代码可以归结为:

prepareContent(pdContenStream, "pdf.value.TDVentilator");
prepareContent(pdContenStream, "...

然后:你可能会把这些东西放在它自己的类中,在这个类中你把pdContentStream变成一个域;以git摆脱每次调用都需要该参数的情况。

在那之后,应该研究如何更好地"组织"这些字符串。写下来毫无意义:

foo("bla");
foo("blub");

相反,您将这些值(如"pdf.value.TDVilator")推送到列表中;然后暗示迭代list/sets/whatevery,从中获取所需的信息。

长话短说:你不会长出怪物。你甚至不允许他们存在。您显示的代码已经严重违反了DRY,绝对不能容忍!

最新更新