DEV Community

Cover image for Building a Document Converter with the Factory Method pattern using Python
Mustafa Elghrib
Mustafa Elghrib

Posted on • Edited on • Originally published at mustafaelghrib.github.io

Building a Document Converter with the Factory Method pattern using Python

Introduction

I am implementing real-world projects using the design patterns to see how we could benefit from them when building our own software, in this article I am building a Document Converter using the Factory Method design pattern, so let's get started!

What is the Factory Method pattern?

Explaining the pattern is out of scope of this article, and you could take a look at the references to know more about this pattern, how we use it and the UML diagram for it. Please make sure you understand the pattern before moving on.

What is the Document Converter?

A Document Converter is a software tool that allows converting documents from one format to another. in this we will build a Document Converter that can convert between various document formats (e.g. PDF, DOCX, HTML) using the Factory Method pattern. Each converter (e.g. PdfConverter, DocxConverter, HtmlConverter) could be implemented as a separate factory that takes in the input document and returns the corresponding output format.

UML diagram for the Document Converter

According to the Factory Method UML diagram, the Creator will be the Converter and the Concrete Creators will be (PDFConverter, DocxConverter, HTMLConverter) and the Product will be the Document and the Concrete Products will be (PDFDocument, DocxDocument, HTMLDocument), so let's see how we implement that in code.

Code implementation

- Step 1: Create the Document class

# document.py

class Document:

    def __init__(self):
        self._file = ""
        self._name = ""

    def read_file(self):
        print(f"Reading {self._file}")

    def process_file(self):
        print(f"Processing {self._file}")

    def convert_file(self):
        print(f"Converting {self._file} to {self._name}")
Enter fullscreen mode Exit fullscreen mode

- Step 2: Create the PDFDocument, DocxDocument and HTMLDocument

# document.py

class PDFDocument(Document):

    def __init__(self, file):
        super().__init__()
        self._file = file
        self._name = "pdf document"

class DocxDocument(Document):

    def __init__(self, file):
        super().__init__()
        self._file = file
        self._name = "docx document"

class HTMLDocument(Document):

    def __init__(self, file):
        super().__init__()
        self._file = file
        self._name = "html document"
Enter fullscreen mode Exit fullscreen mode

- Step 3: Create the Converter class

# converter.py

from document import Document
from abc import ABC, abstractmethod

class Converter(ABC):

    def convert(self, file, to):
        document: Document = self._create_document(file, to)
        document.read_file()
        document.process_file()
        document.convert_file()
        return document

    @abstractmethod
    def _create_document(self, file, to):
        pass
Enter fullscreen mode Exit fullscreen mode

- Step 4: Create the PDFConverter

# converter.py

from document import PDFDocument, HTMLDocument, DocxDocument

class PDFConverter(Converter):

    def _create_document(self, file, to):
        if to == "pdf":
            return PDFDocument(file)
        elif to == "html":
            return HTMLDocument(file)
        elif to == "docx":
            return DocxDocument(file)
        return None

# The DocxConverter and HTMLConverter will be the same
Enter fullscreen mode Exit fullscreen mode

Testing the Document Converter

We could test the PDF Converter as follows:

pdf_converter = PDFConverter()
document = pdf_converter.convert(file="file.pdf", to="docx")
Enter fullscreen mode Exit fullscreen mode

And here is the result:

Reading file.pdf
Processing file.pdf
Converting file.pdf to docx document
Enter fullscreen mode Exit fullscreen mode

Conclusion

So this is just a simple Document Converter that show us how to use the Factory Method design pattern in a real-world application, I hope this article was helpful for you and follow me for more articles like this.

References

Top comments (0)