当前位置: 首页 > 知识库问答 >
问题:

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

彭浩穰
2023-03-14

请原谅这个问题的含混不清,请允许我解释一下。

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

当前版本(v1)包括两个主要变量,一个电源和一个排气。因此,对于每一行内容,都有一个供应值和一个排气值。

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

这就是我对干式原理的问题所在。理论上,两者的代码都已经存在。当它是一个或另一个时,唯一改变的是文本的位置,它现在在两列之间居中。

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

属性。。。。。。。。。。。。。供给耗尽

身高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();

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

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

我能想到的另一种方法是在每个代码块之前创建一个if(),如果是这种情况,则取该块,如果是这种情况,则取该块。再一次,干燥是不存在的(因为相同的if必须出现在每个代码块之前)。

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

干杯:)

共有1个答案

邴奇逸
2023-03-14

查看您的代码:

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, "...

等等然后:您可能会将这些内容放在它自己的类中,在该类中,您将pContentStream作为一个字段;以避免每次调用都需要该参数

之后,应该更好地“组织”这些字符串。没有必要写下:

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

相反,您将诸如“pdf.value.tdventurator”之类的值推到列表中;然后意味着迭代列表/集合/任何东西,从那里获取所需的信息。

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

 类似资料:
  • 问题内容: 如果我用javadoc 编写,它不会出现,因为标签在格式化文本方面具有特殊功能。 如何在Javadoc中显示此字符? 问题答案: 您可以使用为 < 和为 > 。

  • 主要内容:1.DRY 原则,2.实现逻辑重复,3.功能语义重复,4.代码执行重复,5.注释重复,6.数据重复,7.提高代码复用性1.DRY 原则 它的英文描述为:Don’t Repeat Yourself。中文直译为:不要重复自己。将它应用在编程中,可以理解为:不要写重复的代码。 很多人对这条原则存在的误解。实际上,重复的代码不一定违反 DRY 原则,而且。 DRY不是只代码重复,而是“知识”的重复,意思是指业务逻辑。例如由于沟通不足,两个程序员用两种不同的方法实现同样功能的校验。 2.实现逻辑

  • 我从一个看起来很棒的图书馆听到了很多好消息,但我发现自己处于微妙的境地。 这是我工作过的第一个将电话号码存储在数据库中的项目。 我读过一些关于E.164格式的书,我确实打算用这种格式在我的数据库中存储所有电话号码。 我面临的问题是数据源。我无法控制数据源。我只知道我收到了一堆电话号码,它们的格式不一致。有些有国际延伸,有些没有。有些有括号、连字符、前导0等。有些没有。 我如何可能从上述来源提取电话

  • 问题内容: 我有个问题。我正在尝试将一些字符串转换为日期,但我不知道日期到达的格式。 这或许让他们或等。 如何将这些字符串转换为Date?我尝试了这个: 但是,当我打印出someDate时,它的打印方式是这样的:2019-08-05 12:42:48.638 CEST这意味着,但是当我运行以上代码时,日期对象现在变成了,至少可以这样说。 有什么想法可以正确格式化日期格式吗? 问题答案: 你不能!

  • 问题内容: 这是我目前拥有的: 它创建一个CSV文件,其输出如下所示: 我不希望行放在括号中,也不希望在字符串前加引号或’u’。如何在没有所有这些的情况下将行写入csv?谢谢, 问题答案: 您目前正在做的是打印出元组的python字符串表示形式,即返回值。其中包括引号,“ u”和括号等。 相反,您希望数据正确格式化为CSV文件。好吧,尝试模块。毫无疑问,它知道如何格式化CSV文件的格式。

  • 问题内容: 我只是想输出一个先前创建的ArrayList来序列化它,以备将来存储。 但是当我这样做时,我收到运行时错误“ notSerialisableException:部门。 他们是序列化arrayList的一种特殊方法吗? 有人可以告诉我为什么我会收到此错误。 这是代码: 问题答案: 不是问题吗?你的对象是。 您需要在该对象中实现接口。