簡體   English   中英

如何在不損害Java + PDFBox中的DRY原理的情況下格式化代碼?

[英]How to go about formatting code without hurting the DRY principle in java + PDFBox?

請原諒這個問題的陰影,請允許我解釋一下自己。

我使用PDFBox創建了PDFGenerator。 PDF大約有9頁,實際的PDFGenerator.java是具有近4k行代碼的龐然大物,其中很大一部分是PDF內文本的恆定像素位置。

當前版本(v1)包括2個主要變量,一個供氣和一個排氣。 因此,對於某物的每一行都有一個供應值和一個排氣值。

整個過程運行良好,我對整個生成過程感到非常滿意。 但是現在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不存在(因為如果在每個代碼塊之前都必須這樣做)。

我的問題是:通常最好的方法是什么? 我不介意怪物是否從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為字段; 擺脫了每次調用都需要該參數的麻煩。

之后,應該更好地研究“組織”這些字符串。 寫下來毫無意義:

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

相反,您可以將“ pdf.value.TDVentilator”之類的值推送到List中 然后暗示迭代列表/集合/任何內容,以從中獲取所需的信息。

長話短說:你不長怪物。 您甚至不允許它們存在。 你是顯示的代碼是已經干燥的惡劣侵犯應該絕對不能容忍的!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM