1+ """
2+ 24 - Patrones de Diseño: Decoradores
3+ """
4+ # Es un patron estructural que permite agregar funcionalidad a un objeto
5+ # No modifica la estrucura original del objeto
6+ # Se usa para extender el comportamiento de clases sin usar herencia
7+
8+
9+ """
10+ Estructura basica
11+ """
12+ # Componente base: La funcionalidad basica que se desea extender
13+ # Decorador: Funcion o clase que toma un componente y le añade nuevas funcionalidades
14+ # Uso del decorador: Se aplica a un objeto, una funcion o metodo para modificar su comportamiento
15+
16+
17+ """
18+ Ejemplo:
19+ """
20+
21+ # Cafeteria
22+ # Tenemos una cafetería donde vendemos café. Un café básico cuesta $2, pero los clientes pueden agregar extras como leche, azúcar o canela.
23+
24+ class Cafe :
25+ def costo (self ):
26+ return 2 # Precio base del cafe
27+
28+ def descripcion (self ):
29+ return 'Cafe basico'
30+
31+ class Leche :
32+ def __init__ (self , cafe ) -> None :
33+ self .cafe = cafe
34+
35+ def costo (self ):
36+ return self .cafe .costo () + 0.5
37+
38+ def descripcion (self ):
39+ return self .cafe .descripcion () + ' con leche'
40+
41+ class Azucar :
42+ def __init__ (self , cafe ) -> None :
43+ self .cafe = cafe
44+
45+ def costo (self ):
46+ return self .cafe .costo () + 0.2
47+
48+ def descripcion (self ):
49+ return self .cafe .descripcion () + ' con azucar'
50+
51+
52+ # Cafe basico
53+ cafe_basico = Cafe ()
54+ print (f'El cafe que pediste es: { cafe_basico .descripcion ()} y tiene un costo de: ${ cafe_basico .costo ()} ' )
55+
56+ # Cafe con leche
57+ cafe_leche = Leche (cafe_basico )
58+ print (f'El cafe que pediste es: { cafe_leche .descripcion ()} y tiene un costo de: ${ cafe_leche .costo ()} ' )
59+
60+ # Cafe con leche y azucar
61+ cafe_leche_azucar = Azucar (cafe_leche )
62+ print (f'El cafe que pediste es: { cafe_leche_azucar .descripcion ()} y tiene un costo de: ${ cafe_leche_azucar .costo ()} ' )
63+
64+ """
65+ ¿Cuándo usar el patrón decorador?
66+ """
67+ # Cuando queremos extender funcionalidades sin modificar el código original.
68+ # Para modularizar y reutilizar código fácilmente.
69+ # Cuando necesitamos aplicar múltiples comportamientos dinámicos (Ej: logging, permisos, validaciones, caching).
70+
71+ """
72+ Extra
73+ """
74+
75+ def call_counter (function ):
76+ def counter_function ():
77+ counter_function .call_count += 1
78+ print (
79+ f"La función '{ function .__name__ } se ha llamado { counter_function .call_count } ' veces." )
80+ return function
81+
82+ counter_function .call_count = 0
83+ return counter_function
84+
85+
86+ @call_counter
87+ def example_function_1 ():
88+ pass
89+
90+
91+ @call_counter
92+ def example_function_2 ():
93+ pass
94+
95+
96+ example_function_1 ()
97+ example_function_1 ()
98+ example_function_1 ()
99+ example_function_2 ()
100+ example_function_1 ()
101+ example_function_2 ()
102+ example_function_2 ()
0 commit comments