Автор: Сибагатуллин Алик
Паттерн посетитель - поведенческий паттерн проектирвоания, который описывает операцию, выполняемую с каждым объектом из некоторой структуры.
Данный паттерн позволяет определить новую операцию, не изменяя классы этих объектов.Поведенческий паттерн проектирвоания, который описывает операцию, выполняемую с каждым объектом из некоторой структуры. Посетитель (англ. visitor) — поведенческий шаблон проектирования, описывающий операцию, которая выполняется над объектами других классов. При изменении visitor нет необходимости изменять обслуживаемые классы.
Паттерн Visitor следует использовать, если:
-
Имеются различные объекты разных классов с разными интерфейсами, но над ними нужно совершать операции, зависящие от конкретных классов;
-
Необходимо над структурой выполнить различные, усложняющие структуру операции;
-
Часто добавляются новые операции над структурой.
-
Упрощается добавление новых операций;
-
Объединение родственных операции в классе Visitor;
-
Класс Visitor может запоминать в себе какое-то состояние по мере обхода контейнера.
-
Принцип Open/Closed: легко ввести новое поведение в классе, которое может работать с объектами разных классов без внесения изменений в эти классы.
-
Принцип единой ответственности: несколько версий одного и того же поведения могут работать в одном и том же классе.
-
Добавление сущностей: добавление сущности в метод посетителя очень просто, поскольку нам нужно вносить изменения только в класс посетителя, и это не повлияет на существующий элемент.
-
Обновление логики: если логика работы обновляется, нам нужно внести изменения только в реализацию посетителя, а не во все классы элементов.
-
Много обновлений: мы должны обновлять каждого посетителя всякий раз, когда класс добавляется или удаляется из основной иерархии.
-
Трудно расширить: если классов посетителей слишком много, становится очень сложно расширить весь интерфейс класса.
-
Отсутствие доступа: иногда посетители могут не иметь доступа к закрытым полям определенных классов, с которыми они должны работать.
-
Затруднено добавление новых классов, поскольку нужно обновлять иерархию посетителя и его сыновей
Input
class Courses_At_GFG:
def accept(self, visitor):
visitor.visit(self)
def teaching(self, visitor):
print(self, "Taught by ", visitor)
def studying(self, visitor):
print(self, "studied by ", visitor)
def __str__(self):
return self.__class__.__name__
class SDE(Courses_At_GFG): pass
class STL(Courses_At_GFG): pass
class DSA(Courses_At_GFG): pass
""" Abstract Visitor class for Concrete Visitor classes:
method defined in this class will be inherited by all
Concrete Visitor classes."""
class Visitor:
def __str__(self):
return self.__class__.__name__
""" Concrete Visitors: Classes visiting Concrete Course objects.
These classes have a visit() method which is called by the
accept() method of the Concrete Course_At_GFG classes."""
class Instructor(Visitor):
def visit(self, crop):
crop.teaching(self)
class Student(Visitor):
def visit(self, crop):
crop.studying(self)
"""creating objects for concrete classes"""
sde = SDE()
stl = STL()
dsa = DSA()
"""Creating Visitors"""
instructor = Instructor()
student = Student()
"""Visitors visiting courses"""
sde.accept(instructor)
sde.accept(student)
stl.accept(instructor)
stl.accept(student)
dsa.accept(instructor)
dsa.accept(student)
Output
SDE Taught by Instructor
SDE studied by Student
STL Taught by Instructor
STL studied by Student
DSA Taught by Instructor
DSA studied by Student
-
Рекурсивные структуры. Метод посетителя очень хорошо работает с рекурсивными структурами, такими как деревья каталогов или XML-структуры. Объект Посетитель может посетить каждый узел в рекурсивной структуре.
-
Выполнение операций: мы можем использовать метод посетителя, когда нам нужно выполнять операции со всеми элементами сложного объекта, такого как дерево.