I'm building an application that compiles a single PDF document from multiple source PDF documents as follows: it takes the first page of each source document, stamps certain information on top of each of those pages, and then combines all those "first pages" into an output PDF document. Assume the source PDFs already exist.
I'm using a third-party class library to manipulate the PDFs, i.e. extract the first pages, apply the stamped information, and combine pages to output the resulting PDF. My goal is to keep those PDF manipulation operations independent of my domain logic layer so it will be easier to swap out the third-party library if needed in the future. For this, I'd like to make use of an anti-corruption layer.
I imagine my domain will consist of one class (at this point):
PdfDocument. The domain logic layer will load a collection of
PdfDocument objects from file or another type of input stream and make use of services exposed by the anti-corruption layer to produce a single output document which has the characteristics I mentioned earlier. I can envision two possible ways of architecting this:
expose the following distinct services on the anti-corruption layer: 1.) extract the first page of a PDF document, i.e. return a
PdfDocumentthat is one page, 2.) stamp provided text at the top of a provided
PdfDocument, i.e. return a new
PdfDocumentthat contains the stamped text, and 3.) combine multiple
PdfDocumentobjects into one
PdfDocument, i.e. return a new
PdfDocumentthat is all pages from the provided
expose a single service on the anti-corruption layer which takes a collection of
PdfDocuments and returns a single
PdfDocumentwith the aforementioned characteristics.
The first approach seems more in line with separation of concerns because the second approach would have to take on a lot of the domain logic considerations such as "how many pages do I extract?", "do I stamp every page?", and "which of the extracted pages to I include in the output?". However, the first approach is much-less efficient because each service returns a
PdfDocument. The third-party library I'm using has a
Document class and an intermediate class --
Page -- which represents a page belonging to a whole PDF
Document. If I use the first approach, the third-party library would have to bundle everything up into a
Document and then output a
PdfDocument for each service. However, if I use the second approach, I can more-efficiently operate on each PDF because the input PDFs can be broken down into
Page objects to which the stamps could then be directly applied, and those
Page objects could then be combined into the resulting
Document and only then returned as a
I've considered adding a
PdfDocumentPage class to my model as one solution to this, but then my model is taking on concerns that it shouldn't necessarily have. I have no need for the notion of a "page" in my model other than to facilitate a more-efficient use of the third-party library, and that, to me, defeats the purpose of the anti-corruption layer.
Please help me work through this!