Sobreingeniería en software: cómo complicar lo sencillo sin necesidad

Sobreingeniería en software: cómo complicar lo sencillo sin necesidad

Víctor Manuel Cañada, Mobile Development - Expert

Víctor Manuel Cañada

Mobile Development - Expert

21 de octubre de 2024

Todos hemos estado allí. Te sientas frente a tu flamante Macbook pro con procesador M3 y 32GB de RAM (sí, esa bestialidad que nos da SNGULAR y que tanto nos merecemos), listo para diseñar la próxima gran cosa en software. Tienes un café en la mano, un millón de ideas en la cabeza y un arsenal de patrones de diseño que acabas de aprender. ¿Qué podría salir mal? Pues... ¡la sobreingeniería!

¿Qué es la sobreingeniería?

Imagina que quieres construir una casita en el árbol para tus sobrinos. Lo más lógico sería armar algo sencillo: unas tablas, unos clavos, ¡y listo! Pero de repente te emocionas y decides instalar un sistema de poleas, puertas automáticas, sistemas de alarma, paneles solares y, por qué no, un ascensor. ¿Resultado? Tus sobrinos ahora necesitan un manual de 50 páginas para entrar a su casita.

En software, la sobreingeniería es exactamente eso: añadir capas y capas de complejidad que no son necesarias. Es como si en lugar de usar una simple lista para almacenar unos números, decides implementar tu propia estructura de datos con herencia múltiple, patrones de fábrica, y un sistema de eventos que ni tú mismo entiendes del todo. ¿Por qué? Porque puedes.

El efecto de la sobreingeniería cuando empezamos a aprender arquitectura del software

A medida que avanzamos  en el mundo del desarrollo de software, es fácil caer en la trampa de la sobreingeniería. ¿Por qué? Pues porque es emocionante, suena sofisticado, y quieres demostrar que puedes manejar patrones de diseño como un verdadero profesional. Estás aprendiendo sobre arquitecturas limpias, microservicios, inyección de dependencias y toda esa “movida molona que te pone tontorrón”, y te preguntas: ¿Por qué no usarlos todos en mi proyecto?

La realidad es que, aunque los patrones de diseño y las arquitecturas complejas son herramientas poderosas, no siempre son necesarias. Es completamente normal querer probar todo lo que aprendes. Es parte del proceso de crecimiento. El problema viene cuando te das cuenta de que, después de todo, quizás no necesitabas esa fábrica abstracta para crear un único objeto de configuración en tu aplicación.

developers-working-on-code-2024-06-21-23-36-28-utc.webp

El problemón de las clases base que no son tan base

Y hablando de fábricas abstractas y demás “pamplinadas”, hablemos de las clases base. Sí, esas que deberían ser la piedra angular de tu arquitectura pero terminan convirtiéndose en una trampa mortal para la simplicidad.

El uso de clases base puede parecer una idea genial. Piensas: «voy a agrupar todo este código repetido en una clase padre, y listo, todas las hijas heredan esta maravilla». Pero, ¿qué pasa cuando esa clase base termina siendo un monstruo de Frankenstein con más métodos de los que cualquiera puede recordar? De repente, tu clase base se convierte en un laberinto que oculta el comportamiento normal de las clases hijas, como, por ejemplo, los ciclos de vida en Android. ¡Nada como intentar depurar un bug y descubrir que está enterrado en alguna sobrecargada función de tu clase base, oculta por la niebla del override!

Además, suele ocurrir, que no todas las funcionalidades que agrupas en tu clase base son necesarias para todas las clases que heredan de ella. Imagina que decides que todas las instancias de tu clase base Ave de tu programa deben saber nadar porque, bueno, ¿por qué no? Ahora cada vez que alguien cree una instancia de un objeto que herede de tu clase base Aver (por ejemplo el objeto que representa al enigmático "polloCamperoTerrestre"), tiene que lidiar con métodos de natación que no necesita, todo porque alguien (tú en un momento de inspiración excesiva) decidió que sería útil... por si acaso.

¿Arquitectura prefabricada? ¡No, gracias!

Sigamos con los excesos y hablemos de esas arquitecturas ya montadas que vienen con todo el combo: librerías para peticiones, manejadores de eventos, caché y quién sabe cuántas cosas más. Sí, suena práctico y tentador. Todo está listo para usar, empaquetado con un moño bonito. Pero… spoiler alert: lo que ganas en conveniencia, lo pierdes en flexibilidad.

Imagina que te mudas a una casa totalmente amueblada. Puede parecer una ganga, pero luego te das cuenta de que no te gusta el sofá, odias las cortinas y esa lámpara en forma de piña te da escalofríos. Pero, como todo venía en el paquete, ahora estás atrapado con cosas que no necesitas y que no puedes cambiar sin hacer un gran esfuerzo.

En software, usar una arquitectura prefabricada puede llevar a un escenario similar. Terminas utilizando librerías que quizás no son las mejores para tu proyecto, simplemente porque vienen con la arquitectura. Y lo peor de todo, te obliga a diseñar tu software alrededor de esas decisiones pre-tomadas, en lugar de construir algo que realmente se adapte a tus necesidades.

Lo ideal es que las arquitecturas, librerías y herramientas que elijas sean un traje hecho a medida para tu proyecto, no un disfraz genérico de Halloween. No tengas miedo de crear tu propio camino y elegir lo que realmente necesitas, en lugar de acoplarte a lo que ya está hecho.

team-discussing-mobile-application-architecture-2024-01-16-19-05-03-utc.webp

Conclusión

La sobreingeniería es como esa voz en tu cabeza que te dice que necesitas más complejidad para ser mejor desarrollador. Pero, en realidad, ser un buen desarrollador implica saber cuándo dejar de añadir capas y cuándo simplificar las cosas. Menos capas, más claridad. Esa es la verdadera habilidad. Y hablando de claridad, ¡ojo con esas clases base que terminan ocultando más de lo que revelan! Recuerda, una clase base debe ser eso mismo, una base, no un cajón de sastre donde todo termina amontonado.

Por último, no te dejes seducir por arquitecturas prefabricadas que te atan a decisiones que no son ideales para tu proyecto. Construye tu arquitectura con las herramientas y librerías que realmente necesitas, y no más. Al final del día, tu objetivo es resolver un problema de la manera más eficiente y clara posible, no crear un enigma que ni tú puedas resolver.

Así que la próxima vez que te encuentres tentado a añadir una nueva capa de abstracción "por si acaso", “porque mola y he visto que Uncle Bob lo explica en su último gran libro”, recuerda: a veces, la mejor solución es la más sencilla. ¡No compliques lo que no necesitas complicar!

¡Nos vemos en el próximo artículo, donde seguiremos desentrañando los misterios del desarrollo! Hasta entonces….

¡Que la fuerza del Pollo Campero te acompañe 🐔!

Víctor Manuel Cañada, Mobile Development - Expert

Víctor Manuel Cañada

Mobile Development - Expert

Descubrí mi pasión por la programación a los 8 años con un MSX de 8 bits que usaba Basic. El manual del ordenador me sirvió para aprender lógica de programación, marcando mi vida desde entonces. Me motiva aprender y compartir conocimientos. Disfruto de series y películas de fantasía épica y thrillers psicológicos. También me apasiona recorrer rutas en moto, buscando paisajes remotos y carreteras con curvas. Mi truco de programación: Si algo va mal, usa "Pollo Campero" como clave en tus logs de depuración.


Nuestras últimas novedades

¿Te interesa saber cómo nos adaptamos constantemente a la nueva frontera digital?

Contract Testing as a Service: apoya a tus clientes
Contract Testing as a Service: apoya a tus clientes

Tech Insight

21 de noviembre de 2024

Contract Testing as a Service: apoya a tus clientes

Innovación de impacto: Cómo evaluar y diseñar productos digitales sostenibles
Innovación de impacto: Cómo evaluar y diseñar productos digitales sostenibles

Tech Insight

5 de noviembre de 2024

Innovación de impacto: Cómo evaluar y diseñar productos digitales sostenibles

PactFlow & Contract Testing: Un caso de uso empresarial
PactFlow & Contract Testing: Un caso de uso empresarial

Tech Insight

14 de octubre de 2024

PactFlow & Contract Testing: Un caso de uso empresarial

Configuración de Tareas Personalizadas de Lint en Gradle con Kotlin DSL
Configuración de Tareas Personalizadas de Lint en Gradle con Kotlin DSL

Tech Insight

7 de octubre de 2024

Configuración de Tareas Personalizadas de Lint en Gradle con Kotlin DSL