Método de visitante: patrones de diseño de Python

Visitor Method es un patrón de diseño de comportamiento que nos permite separar el algoritmo de una estructura de objeto en la que opera. Nos ayuda a agregar nuevas funciones a una jerarquía de clases existente de forma dinámica sin cambiarla. Todos los patrones de comportamiento demostraron ser los mejores métodos para manejar la comunicación entre los objetos. De igual forma, se utiliza cuando tenemos que realizar una operación sobre un grupo de objetos de tipo similar.
Un método de visitante consta de dos partes: 

  • método llamado Visit() implementado por el visitante y usado y llamado para cada elemento de la estructura de datos.
  • Clases visitables que proporcionan métodos Accept() que aceptan un visitante

Componentes de diseño

  • Cliente: la clase Cliente actúa como consumidor de las clases del patrón de diseño del visitante. Puede acceder a los objetos de la estructura de datos y puede indicarles que acepten un visitante para el procesamiento futuro.
  • Visitante: una clase abstracta que se utiliza para declarar operaciones de visita para todas las clases visitables.
  • Visitante Concreto: Cada Visitante será responsable de diferentes operaciones. Para cada tipo de visitante se deben implementar todos los métodos de visita, declarados en abstracto visitante.
  • Visitable: esta clase declara operaciones de aceptación. También actúa como el punto de entrada que permite que un visitante visite un objeto.
  • Visitable concreto: estas clases implementan la clase Visitable y definen la operación de aceptación. El objeto visitante se pasa a este objeto mediante la operación de aceptación.

Problema sin usar el Método Visitante

Imagine que está manejando la gestión de software de GeeksforGeeks y han iniciado ciertos cursos como DSA, SDE y STL que definitivamente son útiles para los estudiantes que se están preparando para las empresas basadas en productos. Pero, ¿cómo manejará todos los datos de cursos, instructores, estudiantes, clases, identificaciones en su base de datos? Si opta por un enfoque simple y directo para manejar una situación así, definitivamente terminará solo con un desastre.
 

Visitante-problema-diagrama

Visitante-problema-diagrama

Solución utilizando el Método Visitante

Veamos la solución al problema descrito anteriormente. El método Visitor sugiere agregar un nuevo comportamiento en una clase separada llamada clase Visitor en lugar de mezclarlo con las clases ya existentes. Pasaremos el objeto original al método del visitante como parámetros para que el método acceda a toda la información necesaria.
 

Python3

""" The Courses hierarchy cannot be changed to add new
   functionality dynamically. Abstract Crop class for
 Concrete Courses_At_GFG classes: methods defined in this class
 will be inherited by all Concrete Courses_At_GFG classes."""
 
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__
 
 
"""Concrete Courses_At_GFG class: Classes being visited."""
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)

Producción

SDE Taught by  Instructor
SDE studied by  Student
STL Taught by  Instructor
STL studied by  Student
DSA Taught by  Instructor
DSA studied by  Student

Diagrama UML

El siguiente es el diagrama UML para el método de visitante

UML-diagrama-visitante-método

UML-diagrama-visitante-método

Ventajas

  • Principio abierto/cerrado: es fácil introducir un nuevo comportamiento en la clase que puede funcionar con objetos de diferentes clases sin realizar cambios en estas clases.
  • Principio de responsabilidad única: se pueden operar múltiples versiones del mismo comportamiento en la misma clase.
  • Adición de entidades: agregar una entidad en el Método de visitante es fácil, ya que tenemos que realizar cambios solo en la clase de visitante y no afectará el elemento existente.
  • Actualización de la lógica: si se actualiza la lógica de operación, entonces debemos realizar cambios solo en la implementación del visitante en lugar de hacerlo en todas las clases de elementos.

Desventajas

  • Muchas actualizaciones: tenemos que actualizar a todos y cada uno de los visitantes cada vez que se agrega o elimina una clase de la jerarquía principal
  • Difícil de extender: si hay demasiadas clases de visitantes, se vuelve muy difícil extender toda la interfaz de la clase.
  • Falta de acceso: a veces, los visitantes pueden no tener acceso al campo privado de ciertas clases con las que se supone que deben trabajar.

Aplicabilidad 

  • Estructuras recursivas: Visitor Method funciona muy bien con estructuras recursivas como árboles de directorios o estructuras XML. El objeto Visitor puede visitar cada Node en la estructura recursiva
  • Realización de operaciones: podemos usar el método de visitante cuando tenemos que realizar operaciones en todos los elementos del objeto complejo como Tree.

Lectura adicional: método de visitante en C++

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *