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
PdfDocument
that is one page, 2.) stamp provided text at the top of a providedPdfDocument
, i.e. return a newPdfDocument
that contains the stamped text, and 3.) combine multiplePdfDocument
objects into onePdfDocument
, i.e. return a newPdfDocument
that is all pages from the providedPdfDocument
s combined.expose a single service on the anti-corruption layer which takes a collection of
PdfDocument
s and returns a singlePdfDocument
with 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 PdfDocument
.
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!