To begin with, let's consider a simple example. Suppose we have a class hierarchy consisting of Document, Paragraph, and BulletPoint classes, which represent documents, paragraphs, and bullet points, respectively. The Document class contains a list of Paragraph objects, and each Paragraph object contains a list of BulletPoint objects.
To solve these problems, we can use the Visitor design pattern. In this pattern, the print() method is separated from the Document class and implemented as a separate PrintVisitor class, which accepts a Document object as an argument and applies the appropriate algorithm to it.
Here's how we would implement the PrintVisitor class in Swift: