Skip to content

Latest commit

 

History

History
144 lines (82 loc) · 6.4 KB

Visitor.md

File metadata and controls

144 lines (82 loc) · 6.4 KB

Паттерн Visitor / "Посетитель"

Автор: Сибагатуллин Алик


Паттерн посетитель - поведенческий паттерн проектирвоания, который описывает операцию, выполняемую с каждым объектом из некоторой структуры.

Данный паттерн позволяет определить новую операцию, не изменяя классы этих объектов.Поведенческий паттерн проектирвоания, который описывает операцию, выполняемую с каждым объектом из некоторой структуры. Посетитель (англ. visitor) — поведенческий шаблон проектирования, описывающий операцию, которая выполняется над объектами других классов. При изменении visitor нет необходимости изменять обслуживаемые классы.

Использование паттерна Visitor

Паттерн Visitor следует использовать, если:

  1. Имеются различные объекты разных классов с разными интерфейсами, но над ними нужно совершать операции, зависящие от конкретных классов;

  2. Необходимо над структурой выполнить различные, усложняющие структуру операции;

  3. Часто добавляются новые операции над структурой.

image

Преимущества:

  • Упрощается добавление новых операций;

  • Объединение родственных операции в классе Visitor;

  • Класс Visitor может запоминать в себе какое-то состояние по мере обхода контейнера.

  • Принцип Open/Closed: легко ввести новое поведение в классе, которое может работать с объектами разных классов без внесения изменений в эти классы.

  • Принцип единой ответственности: несколько версий одного и того же поведения могут работать в одном и том же классе.

  • Добавление сущностей: добавление сущности в метод посетителя очень просто, поскольку нам нужно вносить изменения только в класс посетителя, и это не повлияет на существующий элемент.

  • Обновление логики: если логика работы обновляется, нам нужно внести изменения только в реализацию посетителя, а не во все классы элементов.

Недостатки:

  • Много обновлений: мы должны обновлять каждого посетителя всякий раз, когда класс добавляется или удаляется из основной иерархии.

  • Трудно расширить: если классов посетителей слишком много, становится очень сложно расширить весь интерфейс класса.

  • Отсутствие доступа: иногда посетители могут не иметь доступа к закрытым полям определенных классов, с которыми они должны работать.

  • Затруднено добавление новых классов, поскольку нужно обновлять иерархию посетителя и его сыновей

VisitorDiagram svg

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-структуры. Объект Посетитель может посетить каждый узел в рекурсивной структуре.

  • Выполнение операций: мы можем использовать метод посетителя, когда нам нужно выполнять операции со всеми элементами сложного объекта, такого как дерево.