使用模板模式设计通用过程

时间:2011-12-19 21:20:09

标签: java templates design-patterns abstract-class

我有一个例程,我反复为许多项目做,我想概括它。我使用iText进行PDF操作。

假设我在一个文件夹中有2000个PDF,我需要将它们压缩在一起。假设每个拉链的限制为1000个PDF。因此,zip的名称将遵循此规则:job name + job sequence。例如,前1000张PDF的zip名称为XNKXMN + AA,第二个zip名称为XNKXMN + AB。在压缩这些PDF之前,我需要为每个PDF添加一些文本。文字看起来像job name + job sequence + pdf sequence。因此,第一个 zip中的第一个PDF将包含此文XNKXMN + AA + 000001,之后的XNKXMN + { {1}} + AA。这是我的尝试

首先,我有抽象的句子000002代表我的文字。

GenericText

public abstract class GenericText { private float x; private float y; private float rotation; /** * Since the text that the user want to insert onto the Pdf might vary * from page to page, or from logical document to logical document, we allow * the user to write their own implementation of the text. To give the user enough * flexibility, we give them the reference to the physical page index, the logical page index. * @param physcialPage The actual page number that the user current looking at * @param logicalPage A Pdf might contain multiples sub-documents, <code>logicalPage</code> * tell the user which logical sub-document the system currently looking at */ public abstract String generateText(int physicalPage, int logicalPage); GenericText(float x, float y, float rotation){ this.x = x; ... } } :我的通用API,用于执行上述操作

JobGenerator.java

所以现在在我的主要班级我会这样做

public String generatePrintJob(List<File> pdfList, String outputPath,
        String printName, String seq, List<GenericText> textList, int maxSize)
for (int currentPdfDocument = 0; currentPdfDocument < pdfList.size(); currentPdfDocument++) {
    File pdf = pdfList.get(currentPdfDocument);
    if (currentPdfDocument % maxSize != 0) {
        if(textList != null && !textList.isEmpty()){
             for(GenericText gt : textList){
                 String text = gt.generateText(currentPdfDocument, currentPdfDocument)
                 //Add the text content to the PDF using PdfReader and PdfWriter
             }  
        } 
        ...
    }else{
          //Close the current output stream and zip output stream
          seq = Utils.getNextSeq(seq);
          jobPath = outputPath + File.separator + printName + File.separator + seq + ".zip"
          //Open new zip output stream with the new <code>jobPath</code>
    }
}
}

我对此设计的问题是,即使我将PDF正确存档到两个zip文件中,文本也没有正确反映。打印和序列不会相应更改,对于前1000个而言,对于2000 PDF而不是final String printName = printNameLookup.get(baseOutputName); String jobSeq = config.getPrintJobSeq(); final String seq = jobSeq; GenericText keyline = new GenericText(90, 640, 0){ @Override public String generateText(int physicalPage, int logicalPage) { //if logicalPage = 1, Utils.right(String.valueOf(logicalPage), 6, '0') -> 000001 return printName + seq + " " + Utils.right(String.valueOf(logicalPage), 6, '0'); } }; textList.add(keyline); JobGenerator pjg = new JobGenerator(); pjg.generatePrintJob(...,..., printName, jobSeq, textList, 1000); + XNKXMN保留AA + XNKXMN并更改为{{1} } + AA用于后来的1000. 我的设计似乎存在缺陷,请帮助

修改

查看XNKXMN代码后,我看到了我的问题。我创建AB,希望在pdf页面的任何地方添加文本,而不会影响流程的基本逻辑。但是,作业顺序根据逻辑定义,因为如果一个ZIP要处理的PDF太多(&gt; toto2),则需要递增。我需要重新考虑一下。

1 个答案:

答案 0 :(得分:4)

当您创建匿名GenerateText时,您在重写的final seq方法中使用的generateText确实是最终的,并且始终保持创建时给定的值。您在seq elsegeneratePrintJob内进行的更新不会做任何事情。

更一般地说,您的代码看起来非常复杂,您应该退后一步并进行一些重大的重构。

修改

我会尝试不同的东西,没有模板方法模式:

int numberOfZipFiles = 
      (int) Math.ceil((double) pdfList.size() / maxSize);  

for (int iZip = 0; iZip < numberOfZipFiles; iZip++) {
  String batchSubName = generateBatchSubName(iZip); // gives AA, AB,...

  for (int iFile = 0; iFile < maxSize; iFile++) {
     int fileNumber = iZip * maxSize + iFile;
     if (fileNumber >= pdfList.size()) // can happen for last batch
        return;
     String text = jobName + batchSubName + iFile;
     ... add "text" to pdfList.get(fileNumber)
  }
}

但是,您可能还想维护模板模式。在这种情况下,我会保留上面写的for循环,但我会将生成方法更改为genericText.generateText(iZip, iFile),其中iZip = 0给出AA,iZip = 1给出AB等等:

for (int iZip = 0; iZip < numberOfZipFiles; iZip++) {
  for (int iFile = 0; iFile < maxSize; iFile++) {
     int fileNumber = iZip * maxSize + iFile;
     if (fileNumber >= pdfList.size()) // can happen for last batch
        return;
     String text = genericText.generateText(iZip, iFile);
     ... add "text" to pdfList.get(fileNumber)
  }
}

也可能有genericText.generateText(fileNumber)本身可以分解AA000001中的fileNumber等等。但这有点危险,因为maxSize会在两个不同的地方使用,并且可能容易出错这样的数据。