You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesi贸n a prueba de IA

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

1 D铆as
10 Hrs
12 Min
34 Seg

Patr贸n Decorator en Python

19/27
Resources

What is the Decorator Pattern?

The Decorator Pattern is a structural design pattern that allows to dynamically add responsibilities to objects. This pattern is especially useful when we need to extend the functionality of an object without altering its original structure. Often, it is necessary to add additional logic without modifying the existing behavior, which is precisely the essence of what the Decorator Pattern offers.

What are the advantages of the Decorator Pattern?

This pattern allows for flexible composition of additional behaviors. If you have multiple decorators, you can combine them to augment the logic on a base behavior. Thus, it acts as a modular and flexible way for developers to adapt the functionality of their application to different situations without having to rewrite the code base.

When should you apply the Decorator Pattern?

The Decorator Pattern is useful when you need to combine multiple behaviors in a modular way. Imagine that you have a desired behavior and, around it, you need another behavior; in this case, the pattern allows you to compose them. Also, it is ideal for situations where you need to add functionality at runtime due to a specific condition in the code or context.

How to implement the Decorator Pattern?

Implementing the Decorator Pattern may seem complex at first, but it can be simplified by following these five steps:

  1. Define an interface or abstract class: This describes the behavior of the base object, which has the main behavior.

  2. Implement the interface in concrete classes: Here, the behavior is abstracted to an interface and then implemented in several concrete classes.

  3. Create an abstract decorator class: This class also implements the interface defined in the first step and acts as the basis for the decorators.

  4. Implement concrete decorators: Concrete decorators extend the decorator class and contain the additional behavior that you want to implement.

  5. Wrap basic objects with decorators: Finally, the basic objects are wrapped with the created decorators, allowing the composition of functionalities.

This process becomes more intuitive when applied in code, allowing to clearly visualize how each component interacts.

An Implementation Example

Suppose we have a system for sending notifications, and we want to add different forms of notification dynamically. Here is a basic implementation of the Decorator Pattern in Python:

# Interface for notificationclass Notificacion: def send(self): pass
 # Concrete implementation of basic notificationclass NotificacionBasica(Notificacion): def send(self): return "Notification sent"
 # Abstract decoratorclass class DecoratorNotificacion(Notificacion): def __init__(self, notificacion): self.notificacion = notificacion
 def send(self): return self.notificacion.enviar()
 # Decorator to add a message in the logclass NotificacionConLog(DecoradorNotificacion): def send(self): result = super().send() return f"{result} with log"
 # Use decorator patternnotificacion = NotificacionBasica()notificacion_con_log = NotificacionConLog(notificacion)
print(notificacion_con_log.enviar()) # Output: "Notificacion enviada con registro en el log".

In this example, we have implemented a basic notification and subsequently added a decorator to include a log in the log, thus demonstrating how the Decorator Pattern can be used to modularize and extend functionalities.

Have you ever had the opportunity to apply the Decorator Pattern in a project? Let us know in the comments! This pattern is a valuable tool for many developers and continues to be relevant in modern programming. We encourage you to continue exploring this and other design patterns to enrich your skills as a developer.

Contributions 3

Questions 0

Sort by:

Want to see more contributions, questions and answers from the community?

El patr贸n Decorador (Decorator Pattern) en Python es una herramienta 煤til para a帽adir funcionalidades a objetos de manera din谩mica sin alterar la estructura de las clases existentes. Este patr贸n es especialmente 煤til en situaciones donde la herencia resulta demasiado r铆gida o cuando deseas modificar el comportamiento de objetos espec铆ficos en tiempo de ejecuci贸n, sin afectar a otros objetos de la misma clase. ### Concepto B谩sico El patr贸n Decorador se basa en el principio de que puedes "envolver" un objeto con m煤ltiples capas de "decoradores" que pueden a帽adir o cambiar su comportamiento. Esto se logra al tener los decoradores y el objeto original compartiendo la misma interfaz o clase base. ### Implementaci贸n en Python Aqu铆 tienes un ejemplo sencillo de c贸mo podr铆as implementar el patr贸n Decorador en Python: `class Component`: ` def operation(self`): ` pass` `class ConcreteComponent(Component`): ` def operation(self`): ` return "Componente Concreto"` `class Decorator(Component`): ` def __init__(self, component`): self.\_component = component ` def operation(self`): ` return` self.\_component.operation() `class ConcreteDecoratorA(Decorator`): ` def operation(self`): ` return f"DecoradorConcretoA({self._component.operation()})"` `class ConcreteDecoratorB(Decorator`): ` def operation(self`): ` return f"DecoradorConcretoB({self._component.operation()})"` ### Uso del C贸digo Y aqu铆 te muestro c贸mo utilizar铆as estos objetos en tu c贸digo: `# Crear el objeto original` simple = ConcreteComponent() `print(simple.operation()) # Salida: Componente Concreto` `# A帽adir funcionalidades con los decoradores` decorated = ConcreteDecoratorA(simple) more\_decorated = ConcreteDecoratorB(decorated) `print(decorated.operation()) # Salida: DecoradorConcretoA(Componente Concreto)` `print(more_decorated.operation()) # Salida: DecoradorConcretoB(DecoradorConcretoA(Componente Concreto))` ### Ventajas del Patr贸n Decorador 1. **Flexibilidad:** Permite a帽adir responsabilidades adicionales a objetos espec铆ficos de forma din谩mica sin afectar a otros objetos de la misma clase. 2. **Reutilizaci贸n:** Promueve la reutilizaci贸n de c贸digo y evita clases cargadas con funcionalidades que no siempre se utilizan. ### Consideraciones * El uso excesivo puede resultar en un dise帽o complicado y dif铆cil de entender, especialmente cuando hay muchos decoradores involucrados. * Los objetos pueden terminar con muchas peque帽as clases y objetos envolventes que solo a帽aden una peque帽a funcionalidad espec铆fica. Este patr贸n es muy utilizado en Python, especialmente en frameworks y bibliotecas donde la modificaci贸n de comportamiento sin cambiar el c贸digo original es crucial.
## **Patr贸n Decorador en Python** ### **Analog铆a del Caf茅** Una analog铆a com煤n para entender el Decorador es la de preparar un caf茅. Imagina que tienes un caf茅 simple (el componente base). Puedes a帽adirle leche, az煤car, caramelo, etc. (los decoradores). Cada adici贸n modifica el caf茅 sin cambiar su esencia. ### **Otro Ejemplo Pr谩ctico: Logueo** Python`import` functools `def logger(func):` ` @functools.wraps(func)` ` def wrapper(*args, **kwargs):` ` print(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}"`) result = func(\*args, \*\*kwargs) ` print(f"Result: {result}"`) ` return` result ` return` wrapper `@logger` `def add(x, y):` ` return` x + y `add(3, 4`) En este ejemplo, el decorador `logger` a帽ade la funcionalidad de imprimir un mensaje antes y despu茅s de ejecutar la funci贸n `add`. ### **Decoradores en Python y el Patr贸n Decorador** Los decoradores en Python son una sintaxis az煤car que implementa el patr贸n Decorador. Sin embargo, es importante notar que no todos los usos de decoradores son ejemplos del patr贸n Decorador en su forma m谩s estricta. ### **Casos de Uso Comunes** * **Logging:** Agregar informaci贸n de registro a funciones. * **Validaci贸n de argumentos:** Verificar que los argumentos pasados a una funci贸n sean v谩lidos. * **Caching:** Almacenar resultados de funciones para evitar recalcularlos. * **Transformaci贸n de datos:** Modificar los datos antes o despu茅s de que una funci贸n los procese. ### **Consideraciones Adicionales** * **Orden de los Decoradores:** El orden en que se aplican los decoradores puede afectar el resultado final. * **Decoradores de Clase:** Los decoradores tambi茅n se pueden aplicar a clases para modificar su comportamiento. * **Decoradores con Argumentos:** Los decoradores pueden tomar argumentos para personalizar su comportamiento. ### **Ventajas Adicionales** * **Modularidad:** Permite separar las funcionalidades en diferentes decoradores. * **Extensibilidad:** Facilita la adici贸n de nuevas funcionalidades sin modificar el c贸digo original. **En resumen,** el patr贸n Decorador es una herramienta vers谩til que puede ser utilizada para mejorar la flexibilidad y la modularidad de tu c贸digo. Al entender c贸mo funciona y cu谩ndo usarlo, puedes escribir c贸digo m谩s limpio y mantenible.
El \*\*Patr贸n Decorator\*\* es un patr贸n de dise帽o estructural que permite agregar funcionalidad a objetos de manera flexible y din谩mica sin modificar su estructura original. Este patr贸n es ideal cuando necesitas extender el comportamiento de clases de manera controlada y no quieres modificar el c贸digo existente. \### Conceptos Clave del Patr贸n Decorator 1\. \*\*Objetos Envolventes (Wrappers)\*\*: Los decoradores envuelven un objeto base, a帽adiendo funcionalidades antes o despu茅s de ejecutar los m茅todos del objeto original.2. \*\*Composici贸n sobre Herencia\*\*: Este patr贸n favorece la composici贸n en lugar de herencia, permitiendo extender funcionalidades sin modificar clases existentes.3. \*\*Encadenamiento\*\*: Es posible combinar m煤ltiples decoradores para a帽adir capas de comportamiento. \### Implementaci贸n en Python Supongamos que tienes una clase que representa notificaciones y deseas a帽adir funcionalidades como registro de acciones y cifrado sin modificar la clase base. \#### Paso 1: Crear una Interfaz Com煤n Define una interfaz base que todos los decoradores y la clase original implementar谩n. ```pythonfrom abc import ABC, abstractmethod class Notifier(ABC):聽 聽 @abstractmethod聽 聽 def send(self, message: str):聽 聽 聽 聽 pass``` \#### Paso 2: Implementar la Clase Base Esta es la implementaci贸n b谩sica de la funcionalidad principal. ```pythonclass EmailNotifier(Notifier):聽 聽 def send(self, message: str):聽 聽 聽 聽 print(f"Enviando correo: {message}")``` \#### Paso 3: Crear Decoradores Los decoradores deben implementar la misma interfaz que la clase base, y recibir谩n una instancia del objeto base para extender su funcionalidad. ```pythonclass LoggerDecorator(Notifier):聽 聽 def \_\_init\_\_(self, notifier: Notifier):聽 聽 聽 聽 self.notifier = notifier 聽 聽 def send(self, message: str):聽 聽 聽 聽 print("\[Logger]: Registrando acci贸n de notificaci贸n.")聽 聽 聽 聽 self.notifier.send(message) class EncryptionDecorator(Notifier):聽 聽 def \_\_init\_\_(self, notifier: Notifier):聽 聽 聽 聽 self.notifier = notifier 聽 聽 def send(self, message: str):聽 聽 聽 聽 encrypted\_message = self.\_encrypt(message)聽 聽 聽 聽 print("\[Encryption]: Mensaje cifrado.")聽 聽 聽 聽 self.notifier.send(encrypted\_message) 聽 聽 def \_encrypt(self, message: str) -> str:聽 聽 聽 聽 return "".join(chr(ord(char) + 1) for char in message) 聽# Cifrado b谩sico``` \#### Paso 4: Usar el Patr贸n Decorator Puedes combinar decoradores din谩micamente para a帽adir funcionalidades. ```python# Crear un notificador baseemail\_notifier = EmailNotifier() \# Envolver con un decorador de registrologger\_notifier = LoggerDecorator(email\_notifier) \# Envolver con un decorador de cifradosecure\_logger\_notifier = EncryptionDecorator(logger\_notifier) \# Usar el decorador finalsecure\_logger\_notifier.send("Hola, este es un mensaje importante.")``` \*\*Salida esperada:\*\* ```\[Encryption]: Mensaje cifrado.\[Logger]: Registrando acci贸n de notificaci贸n.Enviando correo: Ipmb-!ftuf!ft!vo!nfttbohf!jnqpsubouf/``` \### Ventajas del Patr贸n Decorator 1\. \*\*Flexibilidad\*\*: Puedes a帽adir funcionalidades de manera din谩mica sin modificar el c贸digo existente.2. \*\*Reutilizaci贸n\*\*: Los decoradores son reutilizables y pueden combinarse en diferentes configuraciones.3. \*\*Cumple con el Principio Abierto/Cerrado\*\*: Las clases est谩n abiertas a la extensi贸n, pero cerradas a la modificaci贸n. \### Aplicaci贸n en la Vida Real El patr贸n Decorator se utiliza com煤nmente en: 1\. \*\*Bibliotecas de GUI\*\*: Para a帽adir comportamientos como bordes, desplazamiento, sombreado.2. \*\*Frameworks web\*\*: Para a帽adir middleware como autenticaci贸n, registro o manipulaci贸n de solicitudes.3. \*\*Manipulaci贸n de datos\*\*: Para transformar, validar o registrar datos antes de procesarlos. \### Decoradores de Python (`@decorator`) En Python, puedes usar la sintaxis de decoradores con funciones para casos simples. \#### Ejemplo con Funciones ```pythondef logger(func):聽 聽 def wrapper(\*args, \*\*kwargs):聽 聽 聽 聽 print(f"Llamando a la funci贸n {func.\_\_name\_\_}")聽 聽 聽 聽 return func(\*args, \*\*kwargs)聽 聽 return wrapper @loggerdef greet(name):聽 聽 print(f"Hola, {name}!") greet("Alice")``` \*\*Salida:\*\*```Llamando a la funci贸n greetHola, Alice!``` \### Conclusi贸n El \*\*Patr贸n Decorator\*\* en Python es una herramienta poderosa tanto en su implementaci贸n orientada a objetos como en su forma funcional (sintaxis `@decorator`). Es ampliamente usado en sistemas donde se necesita a帽adir comportamientos de manera flexible y reutilizable, manteniendo el c贸digo base limpio y extensible.