POO – ¿Cómo pasar datos “hacia arriba” en la abstracción?
Me he topado con un problema al diseñar mi software.
Mi software consta de algunas clases, Bot
, Website
y Scraper
.
Bot
es la clase más abstracta, responsable de gestionar el programa a un nivel alto.
Website
es una clase que contiene datos extraídos de un sitio web en particular.
Scraper
es una clase que puede tener múltiples instancias por Website
. Cada instancia es responsable de una parte diferente de un solo sitio web.
Scraper
tiene una función scrape_data()
que devuelve los datos JSON asociados al Website
. Quiero pasar estos datos a Website
de alguna manera, pero no encuentro una forma de hacerlo ya que Scraper
se encuentra en un nivel de abstracción inferior. Aquí están las ideas que he probado:
En esta idea, Website tendría que consultar al scraper. El scraper ya está consultando al servidor, por lo que esto parece confuso e ineficiente.
class Website:
def __init__(self):
self.scrapers = list()
self.data = dict()
def add_scraper(self, scraper):
self.scrapers.append(scraper)
def add_data(type, json):
self.data[type] = json
...
El problema aquí es que el scraper no tiene conocimiento del diccionario de sitios web. No puede pasar los datos devueltos por Scraper al Website respectivo.
class Bot:
def __init__(self):
self.scrapers = list()
self.websites = dict()
¿Cómo puedo resolver mi problema? ¿Qué reglas más fundamentales o patrones de diseño se aplican a este problema para que pueda utilizarlos en el futuro?
davy.ai
Una posible solución a este problema es utilizar el patrón de diseño Observer. Con este patrón, la clase
Website
se registraría como un observador de la claseScraper
, y la claseScraper
notificaría a sus observadores (es decir, a las instancias deWebsite
) cada vez que tenga nuevos datos que transmitir. Esto es cómo podría lucir:En esta solución, la clase
Observer
define la interfaz que la claseWebsite
necesita implementar para recibir actualizaciones de las instancias deScraper
.Scraper
tiene una referencia a su propia instancia deWebsite
, y cuando tiene nuevos datos para transmitir, notifica a la instancia deWebsite
al llamar a su métodonotify()
. La instancia deWebsite
luego actualiza su propio estado con los nuevos datos al llamar a su métodoadd_data()
. De esta manera, las clasesScraper
yWebsite
permanecen débilmente acopladas y pueden modificarse de forma independiente.Algunos consejos adicionales que pueden ayudar con el diseño de software al trabajar con programación orientada a objetos y patrones de diseño: