Una fábrica de clases es una función que crea y devuelve una clase. Es uno de los poderosos patrones en Python. En esta sección, cubriremos cómo diseñar fábricas de clases y los casos de uso de la misma.
Diseño de una fábrica de clases
Como se mencionó, las fábricas de clases son funciones que crean y devuelven una clase. Puede crear una clase en el momento de la codificación (usando la palabra clave class) y también durante el tiempo de ejecución (usando el tipo). Comencemos con cómo diseñar una fábrica de clases y crear una clase en el momento de la codificación, luego veremos el escenario de la creación de una clase durante el tiempo de ejecución.
Class Factory y palabra clave de clase
Diseñar una fábrica de clases usando la palabra clave class no es más que crear una función que contenga una clase. Veamos el siguiente código:
Python3
def apple_function(): """Return an Apple class, built using the class keyword""" class Apple(object): def __init__(self, color): self.color = color def getColor(self): return self.color return Apple # invoking class factory function Apple = apple_function() appleObj = Apple('red') print(appleObj.getColor())
red
Clase Fábrica y tipo
Usando type podemos crear clases dinámicamente. Pero hacerlo dejará las funciones en el espacio de nombres junto con la clase. Veamos el código para entenderlo mejor.
Python3
def init(self, color): self.color = color def getColor(self): return self.color Apple = type('Apple', (object,), { '__init__': init, 'getColor': getColor, }) appleRed = Apple(color='red') print(appleRed.getColor())
red
El código anterior muestra cómo crear una clase dinámicamente. Pero el problema es que las funciones como init y getColor están saturando el espacio de nombres y tampoco podremos reutilizar la funcionalidad. Mientras que, al usar una fábrica de clases, puede minimizar el desorden y puede reutilizar la función cuando sea necesario. Veamos el siguiente código.
Python3
def create_apple_class(): def init(self, color): self.color = color def getColor(self): return self.color return type('Apple', (object,), { '__init__': init, 'getColor': getColor, }) Apple = create_apple_class() appleObj = Apple('red') print(appleObj.getColor())
red
Es importante tener en cuenta que varias llamadas a create_apple_class devolverán clases distintas.
Cuándo debes escribir Fábricas de clase
Echemos un vistazo a algunos de los casos de uso de las fábricas de clases. Las fábricas de clases son útiles cuando no sabe qué atributos se asignarán en el momento de la codificación.
Atributos de tiempo de ejecución
Las fábricas de clase son necesarias cuando los atributos de la clase difieren según el requisito. Consideremos el caso de un proceso de inicio de sesión. Aquí, consideraremos dos escenarios, ya sea el inicio de sesión tradicional o el uso de un servicio OpenId. Si nos fijamos en el inicio de sesión tradicional, los parámetros son nombre de usuario y contraseña, y además, puede tener autenticación de dos factores. Y, para el servicio OpenId, los parámetros son el nombre del servicio y la dirección de correo electrónico. Este escenario de dos inicios de sesión apunta al hecho de que los atributos de una clase difieren según el servicio de inicio de sesión. Veamos el siguiente código de ejemplo:
Python3
def credentials_cls(need_proxy=False, tfa=False): # need proxy for openId services if need_proxy: print("Open Id Service") keys = ['service_name', 'email_address'] else: print("Traditional Login") keys = ['username', 'password'] # two factor authentication for traditional login if tfa: keys.append('auth_token') class CredentialCheck(object): required_keys = set(keys) def __init__(self, **kwargs): # checking whether key matches based on login service if self.required_keys != set(kwargs.keys()): raise ValueError('Mismatch') # storing the keys and values to the credential object for k, v in kwargs.items(): setattr(self, k, v) return CredentialCheck CredCheck = credentials_cls(False, False) crdTraditional = CredCheck(username='uname', password='******') OpenIDCheck = credentials_cls(True, False) crdOpenID = OpenIDCheck(service_name='sname', email_address='email@gmail.com')
Traditional Login Open Id Service
Modificar atributos de clase
Otra ventaja de usar atributos de clase es que puede manejar atributos de clase y distinguirlos de instancias de clase. Consideremos el escenario donde una clase define un método de clase. Los métodos de clase son métodos que requieren la clase misma para su ejecución en lugar de la instancia de una clase. Puede diseñar un método de clase decorando un método usando el decorador @classmethod. Veamos el siguiente código.
Python3
class Apple(object): color = 'red' @classmethod def classapple(cls): return cls.color appleRed = Apple() appleYellow = Apple() appleGreen = Apple() print("Apple Red: ", appleRed.classapple()) appleYellow.color = 'Yellow' print("Apple Yellow: ", appleYellow.classapple()) appleGreen.color = 'Green' print("Apple Green: ", appleGreen.classapple())
Apple Red: red Apple Yellow: red Apple Green: red
En el código anterior, hemos diseñado una clase llamada Apple que tiene color como atributo. Además de esto, hemos declarado un método de clase llamado classapple usando el decorador @classmethod . La funcionalidad del método classapple es devolver el color de la manzana. Pero puede notar que incluso después de establecer el color de la manzana en amarillo y verde, el objeto devuelve el color rojo predeterminado. Esta limitación se puede superar utilizando una fábrica de clases.
Veamos el siguiente código que define una fábrica de clases llamada create_Apple_subclass. Aquí crearemos una subclase de Apple, subApple, para establecer el color. Finalmente, la fábrica de clases devuelve la subclase.
Python3
class Apple(object): color = 'red' @classmethod def classapple(cls): return cls.color def create_Apple_subclass(new_color): class SubApple(Apple): color = new_color return SubApple sappleYellow = create_Apple_subclass('Yellow') print("Apple Color: ", sappleYellow.classapple()) sappleGreen = create_Apple_subclass('Green') print("Apple Color: ", sappleGreen.classapple())
Apple Color: Yellow Apple Color: Green
Resumen
Las fábricas de clases son poderosos patrones de diseño que aseguran que un proceso dinámico de creación de clases sea legible, organizado y reutilizable. Y, también, las fábricas de clases permiten el cambio de atributos en función del parámetro enviado a la función.
Publicación traducida automáticamente
Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA