Посетитель - позволяет добавлять новые операции к объектам без изменения их классов. Он переносит логику операций в отдельные классы-посетители.

Когда использовать? Когда нужно выполнять разные операции над объектами сложной структуры Когда часто добавляются новые операции Для реализации двойной диспетчеризации

`from abc import ABC, abstractmethod

#Интерфейс элемента (принимает посетителя)

class DocumentElement(ABC): @abstractmethod def accept(self, visitor): pass

#Конкретные элементы

class TextElement(DocumentElement): def init(self, content): self.content = content

def accept(self, visitor): visitor.visit_text(self)

class ImageElement(DocumentElement): def init(self, path, width, height): self.path = path self.width = width self.height = height

def accept(self, visitor): visitor.visit_image(self)

#Интерфейс посетителя

class DocumentVisitor(ABC): @abstractmethod def visit_text(self, element): pass

@abstractmethod def visit_image(self, element): pass

#Конкретные посетители

class HtmlExportVisitor(DocumentVisitor): def visit_text(self, element): print(f"{element.content}

")

def visit_image(self, element): print(f'!')

class MarkdownExportVisitor(DocumentVisitor): def visit_text(self, element): print(f"{element.content}n")

def visit_image(self, element): print(f"!Image")

#Клиентский код

elements = [ TextElement("Привет, мир!"), ImageElement("photo.jpg", 800, 600), TextElement("Это пример паттерна Посетитель") ]

html_visitor = HtmlExportVisitor() markdown_visitor = MarkdownExportVisitor()

print("HTML экспорт:") for element in elements: element.accept(html_visitor)

print("nMarkdown экспорт:") for element in elements: element.accept(markdown_visitor) #weekofpatterns`