La descomposición es dividir una tarea grande en subtareas o funciones más simples y manejables. Históricamente, la descomposición surgió como un principio clave en la programación modular: simplifica la gestión de la complejidad, la testabilidad y la reutilización del código.
Problema: Sin descomposición, el código se convierte en un "monolito": es difícil de leer, mantener y cambiar, y es más complicado escribir pruebas y reutilizar partes del programa.
Solución: En Python, la descomposición se implementa: dividiendo la lógica en funciones, clases, módulos; nombrando de manera clara; utilizando composición y abstracciones. Esto permite escribir código legible y escalable.
Ejemplo de código:
# Código monolítico no compacto numbers = [1, 2, 3, 4] squares = [] for n in numbers: if n % 2 == 0: squares.append(n**2) print(squares) # Variante descompuesta def is_even(n): return n % 2 == 0 def square(n): return n ** 2 def filter_and_apply(numbers, predicate, func): return [func(n) for n in numbers if predicate(n)] numbers = [1, 2, 3, 4] result = filter_and_apply(numbers, is_even, square) print(result)
Características clave:
¿Puede una función implementar toda la lógica de negocio si es pequeña?
A menudo se piensa que si la tarea es pequeña, se permite escribir "una función de 100 líneas". Este es un anti-patrón: incluso una tarea pequeña se complica con el más mínimo cambio; las microfunciones son mucho más fáciles de probar y mantener.
¿Pueden las funciones con la misma lógica pero diferentes nombres considerarse como descomposición?
No, la duplicación de código es una mala descomposición. El código repetido indica límites incorrectamente elegidos para las subtareas. Siempre se debe extraer la funcionalidad repetida en funciones auxiliares.
Ejemplo:
def add_user(): pass # lógica def add_admin(): pass # ¡la misma lógica que arriba!
¿Es necesario descomponer tareas auxiliares si solo se utilizan en un lugar?
Sí, a menudo tales funciones ayudan a simplificar el código incluso con un uso único (por ejemplo, extrayendo condiciones o filtraciones en una función separada).
Un proyecto de procesamiento de datos pasó a través de una enorme función de 300 líneas. Cada error causaba pánico: era imposible entender rápidamente qué y dónde sucedió, la prueba era prácticamente imposible.
Ventajas:
Desventajas:
El mismo proyecto, refactorización: el código se dividió en funciones y clases pequeñas según la lógica principal (lectura, validación, procesamiento, escritura de datos).
Ventajas:
Desventajas: