Acceso a recursos web mediante el patrón de diseño de método de fábrica en Python

Una fábrica es una clase para construir otros objetos, donde crea y devuelve un objeto basado en los parámetros pasados. Aquí, el cliente proporciona materiales a la clase Factory, y la clase Factory crea y devuelve los productos en función del material dado. Una fábrica no es un patrón de diseño, pero sirve como base para el patrón de diseño del método de fábrica.

Antes de entrar en el patrón de diseño del método de fábrica, creemos una fábrica simple . En el siguiente ejemplo, la clase SimpleFactory tiene un método estático llamado build_connection() para crear objetos basados ​​en el parámetro recibido.

Python3

import http.client
from ftplib import FTP
  
  
class SimpleFactory(object):
    
    @staticmethod
    def build_connection(protocol):
        if protocol == 'https':
            return http.client.HTTPSConnection('www.python.org')
        elif protocol == 'ftp':
            return FTP('ftp1.at.proftpd.org')
        else:
            raise RuntimeError('Unknown protocol')
  
  
if __name__ == '__main__':
    
    input_protocol = input('Which protocol to use? (https or ftp):')
    protocol = SimpleFactory.build_connection(input_protocol)
      
    if input_protocol == 'https':
        protocol.request("GET", "/")
        resp = protocol.getresponse()
        print(resp.status, resp.reason)
      
    elif input_protocol == 'ftp':
        resp = protocol.login()
        print(resp)

Veamos la salida 

Producción

Aquí, proporciona el tipo de protocolo como argumento, y la clase de fábrica crea y devuelve el objeto en función del argumento. El punto a tener en cuenta es que la creación de objetos no es responsabilidad del cliente. 

Patrón de diseño de método de fábrica

El patrón de diseño de método de fábrica es idéntico a una fábrica simple, pero su estructura es complicada en comparación con una estructura de fábrica simple. Tiene una clase abstracta que contiene métodos de fábrica (para crear objetos) y métodos de operación (para trabajar con objetos creados). Y las clases concretas que crean objetos se derivan de la clase abstracta. 

Este patrón ayuda a definir una interfaz para crear un objeto. Aquí, las clases que implementan la interfaz deciden qué clase instanciar. Por lo tanto, los métodos de operación en la clase abstracta no necesitan preocuparse por la creación de objetos hasta que se implemente la interfaz del producto.

Nota: si es un principiante, le recomiendo encarecidamente que siga el Método de fábrica: patrones de diseño de Python .

Ventajas del patrón de diseño del método de fábrica

Veamos las ventajas del patrón de diseño de fábrica. Algunos de ellos son:

  1. Hace que el código sea más universal.
  2. Separa las interfaces de la implementación.
  3. Reduce la complejidad del mantenimiento del código.

Acceso a recursos web utilizando un protocolo diferente

Implementemos un programa para acceder a recursos web utilizando el protocolo HTTP o FTP. Aquí, usaremos el sitio ftp.freebsd.org que permite tanto el protocolo HTTP como el FTP. 

Patrón de diseño de método de fábrica

Del diagrama anterior, podemos entender que el diseño tiene una clase abstracta llamada Conector y dos clases concretas: HTTPConnector y FTPConnector. Las dos clases concretas se derivan de la clase Connector y los métodos de fábrica de la clase abstracta utilizan estas clases para la creación de productos. Veamos el código a continuación.  

Python3

import abc
import urllib
import urllib.error
import urllib.request
from bs4 import BeautifulSoup
  
  
class Connector(metaclass=abc.ABCMeta):
    def __init__(self, is_secure):
        self.is_secure = is_secure
        self.port = self.factory_port()
        self.protocol = self.factory_protocol()
  
    @abc.abstractmethod
    def crawl(self):
        pass
  
    def scan(self, con_domain, con_path):
        url = self.protocol + '://'+ con_domain \
              + ':' + str(self.port) + con_path
        print(url)
        return urllib.request.urlopen(url, timeout=10).read()
  
    @abc.abstractmethod
    def factory_protocol(self):
        pass
  
    @abc.abstractmethod
    def factory_port(self):
        pass
  
class HTTPConnector(Connector):
    """ Creates an HTTP Connector """
  
    def factory_protocol(self):
        if self.is_secure:
            return 'https'
        return 'http'
  
    def factory_port(self):
        if self.is_secure:
            return '443'
        return '80'
  
    def crawl(self, data):
        """ crawls web content """
        filenames = []
        soup = BeautifulSoup(data,"html.parser")
        links = soup.table.findAll('a')
          
        for link in links:
            filenames.append(link['href'])
        return '\n'.join(filenames)
  
class FTPConnector(Connector):
    def factory_protocol(self):
        return 'ftp'
  
    def factory_port(self):
        return '21'
  
    def crawl(self, data):
        # converting byte to string
        data = str(data, 'utf-8')
        lines = data.split('\n')
        filenames = []
        for line in lines:
            extract_line = line.split(None, 8)
            if len(extract_line) == 9:
                filenames.append(extract_line[-1])
                  
        return '\n'.join(filenames)
  
if __name__ == "__main__":
    con_domain = 'ftp.freebsd.org'
    con_path = '/pub/FreeBSD/'
  
    con_protocol = input('Choose the protocol \
                    (0-http, 1-ftp): ')
      
    if con_protocol == '0':
        is_secure = input('Use secure connection? (1-yes, 0-no):')
        if is_secure == '1':
            is_secure = True
        else:
            is_secure = False
        connector = HTTPConnector(is_secure)
    else:
        is_secure = False
        connector = FTPConnector(is_secure)
  
    try:
        data = connector.scan(con_domain, con_path)
    except urllib.error.URLError as e:
        print('Cannot access resource with this method', e)
    else:
        print(connector.crawl(data))
         

En este programa nos conectamos a una página web mediante el protocolo HTTP o FTP. La clase abstracta Connector está diseñada para establecer una conexión ( método de escaneo ) y también para rastrear las páginas ( método de rastreo ). Además de esto, proporciona dos métodos de fábrica, factory_protocol y factory_port , para manejar el protocolo y la dirección del puerto.

Echemos un vistazo a la salida.

Producción

Resumen

Una clase de fábrica se usa para crear otras clases. Hace que el código sea más universal. Los métodos de fábrica en las clases de fábrica actúan como una interfaz para crear un objeto, por lo que separan la interfaz de la implementación. Como resultado, las clases pueden implementar estos métodos de interfaz y pueden decidir qué clase instanciar.

Publicación traducida automáticamente

Artículo escrito por SonuGeorge 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 *