En el siguiente artículo, definiré un marco de trabajo (framework) para el desarrollo de sistemas de información digitales. Este marco de trabajo es producto de mi experiencia laboral, habiendo participado en múltiples proyectos con diferentes roles, y tiene como objetivo establecer un estándar de buenas prácticas a la hora de comenzar con un nuevo proyecto que involucre el desarrollo de herramientas de sistemas digitales.
Aunque realmente este marco de trabajo puede considerarse un subconjunto de un marco de trabajo más amplio como el desarrollo de proyectos (independientemente del ámbito o del sector). Como todas las reglas, este marco de trabajo está hecho para romperse y adaptarlo a las distintas necesidades de cada implementador, sea un gran equipo, pequeño o una única persona.
Prefacio
Antes de detallar el flujo del Ciclo de vida del desarrollo de Software es necesario detallar algunos puntos clave que debemos comprender y tener siempre en mente durante todo el proyecto, ya que constituyen la base para un desarrollo sólido y un resultado limpio.
En el ámbito técnico
La importancia del dominio. Antes de comenzar el proyecto es necesario comprender qué es exactamente lo que queremos hacer. En el ámbito de los sistemas de información, la tarea principal consiste en digitalizar procesos o hechos de la realidad y ofrecer una herramienta para visualizar, monitorizar, planear, compartir y modificarlos de forma virtual, sean procesos tangibles (por ejemplo un sistema de inventariado) o abstractos (como un gestor de tareas). En cualquiera de los casos es importante comprender todos los conceptos que forman parte de él, o como mínimo aquellos que se quieren integrar en el sistema, ya que es posible que algunos no sean relevantes o necesarios. A este conjunto de conceptos lo llamaremos dominio y a cada uno de ellos entidad. A partir de este dominio podremos trazar relaciones entre las diferentes entidades, de donde sacaríamos cosas como un diagrama de Entidad Relación para bases de datos relacionales, diagramas de clases para la implementación de casos de uso en código y un largo etcétera.
El código no es más que una herramienta. En cuanto al desarrollo, es importante comprender que programar no es siempre lo mismo que codificar. Si bien muchas veces creemos que la única labor de un desarrollador es escribir código, normalmente la labor es solucionar problemas o hacer un sistema más eficiente, y no siempre esto se consigue a través del código. Desarrollamos para nosotros mismos o para otras personas, y el capital humano es una pieza muy importante ya que el sistema no tiene utilidad o finalidad sin él. En muchos casos es muy importante reconocer previamente otras soluciones al problema en cuestión fuera del ámbito digital, y valorar el aporte e impacto que un programa puede ofrecer al proceso.
Por otra parte, hay muchas formas de programar que pueden directa o indirectamente hacer uso de código, pero pueden también realizarse desarrollos por personas que no necesariamente sepan programar, usando herramientas de programación visual, o simplemente desarrollando procesos con herramientas ya existentes o, hoy en día, incluso LLMs y herramientas de IA. Al fin y al cabo es exactamente lo que hacemos los programadores con el código: siempre usamos herramientas para codificar basadas en otras, usando lenguajes de programación de alto nivel e incluso frameworks encima de ellos.
Escalabilidad. A la hora de implementar la solución es importante tener siempre en mente que el producto final debe estar preparado para sufrir modificaciones, mejoras o expansiones. Esto no significa que en una primera versión deban implementarse todas las ideas a futuro que ni siquiera al momento están definidas, pero sí hacer uso de buenas prácticas que den pie a que en un futuro puedan realizarse eficientemente. Esto incluye también pensar que no se desarrolla un producto perecedero: a diferencia de otros sectores como el de la alimentación, el producto no se consume sino que persiste, lo que implica que en un futuro puedes volver a encontrarte con él. Es muy importante hacerlo no solo eficiente, sino que a veces es mejor sacrificar parte de la eficiencia por la comprensibilidad. Por ejemplo, la mayoría de las veces es más importante escribir unas cuantas líneas de código más, o extraer cálculos in-line a variables con nombres descriptivos, aunque esto signifique un menor rendimiento (que en la mayoría de los casos es imperceptible), para que uno mismo en un futuro al retomarlo pueda comprender exactamente qué hace sin tener que gastar demasiado tiempo en pensarlo. Esto cobra mucha más importancia cuando el trabajo se reparte entre más de una persona.
Producto Mínimo Viable (MVP). Después de presentar estas reglas o conceptos hay que entender que como personas tenemos la capacidad de usar el sentido común y podemos decidir no aplicarlas en determinados casos. Muchas veces podemos perdernos queriendo definir todo al 100%, modelando un dominio, casos de uso y funcionalidades que realmente solo viven en nuestras mentes, notas, papeles y diagramas, pero que al llevarlas a la práctica no surten el efecto y la eficiencia que esperábamos. Por ello es de gran ayuda limitarnos a hacer algo pequeño pero funcional: pensar en aquello que con un menor esfuerzo puede retornar un mayor beneficio, y así probar que la idea planteada realmente funciona o si necesita ciertos cambios.
A veces es mejor deshacer el trabajo. En ocasiones, a mitad del desarrollo podemos darnos cuenta de que lo que estamos haciendo no va a funcionar o no va a cumplir las necesidades que teníamos en mente. Es importante percatarse con suficiente antelación de las fallas que puede tener nuestro planteamiento o sistema, y valorar si merece la pena continuar, o parar para replantear y, si es necesario, desechar y comenzar de nuevo, ya que muchas veces nos obsesionamos con una solución o camino que no llega nunca a donde buscamos.
No todos los problemas tienen solución. Finalmente, es posible que el problema que queremos resolver no tenga solución, o al menos no con las herramientas que tenemos disponibles en ese momento, o que la solución no sea viable sin una inversión de tiempo y esfuerzo que por el momento no podemos o no queremos asumir. En estos casos se pueden tomar muchas medidas; aún así, lo más importante es entender que este caso existe y tenerlo en cuenta. Quizá hay que plantear el problema desde otro punto de vista y aceptar otra manera de trabajar.
Aceptar que todo el trabajo puede tener fallas. Al digitalizar procesos de la vida real es casi imposible detallar todos los casos de uso o edge cases que pueden ocurrir, y muchas veces los pasamos por alto. Por ello tenemos que implementar medidas de salvaguarda para que estos casos no supongan un fallo fatal para el sistema, y tener una forma de recuperar la estabilidad o tolerar estos errores o bugs.
En el ámbito social
La honestidad. Para comenzar, el factor principal de todos los participantes del proyecto es la honestidad y la comunicación clara. Transmitir nuestras dudas al resto del equipo, comunicar lo antes posible los problemas o bugs encontrados, o simplemente ser claros a la hora de estimar tiempos. Diría que este último es uno de los que más falla: muchas veces, por vergüenza o por presión, podemos prometer hacer algo en menos tiempo del que realmente necesitamos, lo cual es contraproducente y genera más tensión a la hora de cumplir con las fechas de entrega. Si no estamos muy seguros de cómo hacer algo, o simplemente sabemos que es complicado, lo mejor es comunicarlo y decir el tiempo que realmente creemos que podemos dedicarle. Y si tampoco lo sabemos, no podemos inventarlo; quizá es mejor decir algo como:
“Ahora mismo no sabría estimar el tiempo que puede llevar esta característica, por lo que no puedo dar una fecha de entrega concreta. Pero puedo investigarlo y plantearlo en unas horas y darte una respuesta más fundada.”
La clara comunicación entre los diferentes participantes. Es importante que todo el equipo conozca con suficiente detalle el alcance general del proyecto y todos los conceptos básicos, aunque muchas veces no parezca directamente necesario para la tarea a desempeñar. En ocasiones hay que tomar decisiones imprevistas o que no tienen una única solución, y comprender el proyecto al completo brinda a todos una mejor respuesta ante esas situaciones. Por otra parte, siempre es interesante agilizar el proceso haciendo una propuesta simple que ahorre tiempo frente a reunirse en todo momento y ralentizar el desarrollo. Esto no significa que durante el proceso no se necesiten reuniones para hacer puestas en común.
Este es el punto donde muchas veces herramientas automatizadas como LLMs u otras herramientas de IA pueden fallar: al no ser humanas ni tener experiencia humana, es posible que tomen decisiones incorrectas o no las más adecuadas en casos donde existen dos soluciones válidas, o que, al estar diseñadas para resolver un problema concreto, pasen por alto ideas que podrían reducir la deuda técnica y favorecer la escalabilidad.
La importancia de dejar las cosas escritas y/o en un medio objetivo y común. Esto aplica tanto a las ideas, planteamientos y bocetos como al material o activo generado. En cuanto al código, existe un estándar como el control de versiones (Git o similares), pero esto también debe aplicar a las tareas y definiciones usando herramientas como GitHub, GitLab, Azure DevOps o la que mejor encaje para el equipo, definiendo features, bugs, épicas…
La comunicación oral es interesante para debatir, pero a veces las personas necesitamos leer algo varias veces, tenerlo como soporte durante el desarrollo, o simplemente pueden olvidársenos detalles que para unos pueden parecer pequeños (esto también está estrechamente ligado con la comunicación clara).
Principio de responsabilidad conjunta. Este principio define la necesidad de hacer responsable de una característica a más de una persona, algo que se consigue mediante peer review, pair coding y similares. Es muy importante que más de una persona verifique y se responsabilice de cada parte del trabajo, lo que ofrece varias ventajas: ayuda a detectar errores que uno mismo, en su proceso de pensamiento durante la implementación, no ha podido percatarse; al explicar a otros el trabajo ya realizado pueden surgir nuevos puntos de vista y darnos cuenta de cosas que antes no veíamos; y, por último, ayuda a generar confianza y deshacerse de la preocupación de que la propia implementación no sea válida, no cumpla los requerimientos o incluya errores.
Corroboración y jerarquía. Por último, es importante que todo el equipo esté de acuerdo con cada decisión o planteamiento. Sin embargo, no siempre es posible llegar a un consenso; en ese caso, lo importante es que alguien pueda tomar una decisión final. Esta decisión puede ser la más acertada o no, pero lo importante es que es una decisión, y siempre es mejor eso que quedarse en el aire, sin avanzar o gastando más recursos de los que se pueden rentabilizar.
Participantes y roles
A continuación se definen los participantes y roles que intervienen en el ciclo. Pueden existir de forma explícita o implícita: una misma persona puede asumir varios roles simultáneamente o en diferentes puntos del proceso, y un rol puede estar repartido entre varias personas. En proyectos pequeños, una única persona puede conformar todo el equipo. Hoy en día, algunos roles pueden ser asistidos o incluso asumidos por herramientas de IA o LLMs.
Participantes externos
- Cliente — define necesidades y alcance. Financia o encarga el proyecto.
- Usuario — usa el sistema. Sus necesidades no siempre coinciden con las del cliente.
Roles internos
- Coordinación — gestión de tiempos, comunicación y toma de decisiones.
- UX/UI — diseño de la experiencia e interfaz.
- Arquitectura — decisiones estructurales del sistema.
- Implementación — escritura del código y lógica de negocio.
- QA / Testing — verificación y control de calidad.
Ciclo de vida
Se denomina ciclo porque, aunque los pasos deben seguirse en orden —es decir, para comenzar uno todos los anteriores deben estar cerrados— se permite volver hacia atrás y revisar o modificar una definición anterior. Hacerlo implica repasar todos los pasos posteriores hasta volver al punto de partida, comportándose como un diagrama de flujo.
Cada paso lleva un identificador siendo la primera inicical la inicial del rol que lidera el paso, es decir, los pasos del 1 al 4 están liderados por el rol de coordinación y del 5 al 9 por el rol de implementación. El último paso siempre es la entrega al cliente.
Bloque I: DPE — Definición y Primera Entrega
Este bloque abarca desde la recepción de la idea inicial hasta la primera entrega funcional al cliente. Su objetivo es transformar una necesidad en un producto real, validado y desplegado.
CDPE1 — Recepción de la idea
Se plantea o se recibe desde el cliente una idea para solucionar un problema. El equipo de gestión trabaja junto al cliente para desarrollarla y definir a grandes rasgos un alcance preliminar: qué características y funcionalidades puede ofrecer el producto y qué beneficio aportará una vez finalizado.
Condiciones de salida: existe una descripción clara del problema y una primera aproximación al alcance, documentadas y compartidas con el equipo.
CDPE2 — Debate de viabilidad técnica
La idea y el planteamiento inicial se transmiten a todo el equipo. Cada rol aporta su punto de vista: se proponen enfoques de implementación, se identifican las herramientas a utilizar, se estima la complejidad de cada ámbito y se evalúa si el proyecto es viable con los conocimientos y recursos actuales. Es habitual que en este paso se señalen puntos débiles de la idea que desde la gestión o el cliente no eran visibles.
Condiciones de salida: el equipo tiene una posición común sobre la viabilidad del proyecto y ha identificado los principales riesgos técnicos.
CDPE3 — Oferta y validación
Se genera una oferta que recoge el alcance acordado, los puntos clave de la implementación, las estimaciones de tiempo y las fechas de entrega previstas. El cliente la revisa, confirma que el alcance refleja fielmente sus necesidades y la valida formalmente. Cualquier ajuste en este punto debe revisarse con el equipo antes de aceptarse.
Condiciones de salida: la oferta está firmada o aprobada por el cliente y el alcance queda cerrado para este bloque.
CDPE4 — Planificación
Con el alcance validado, se planifican los plazos de ejecución, se asignan recursos y se desglosa el trabajo en tareas concretas, finitas y comprensibles para todos los roles. Cada tarea debe tener un responsable claro y una estimación de tiempo realista.
En este paso también se definen las historias de usuario y casos de uso para transmitir con exactitud al equipo el resultado final.
Condiciones de salida: todas las tareas del alcance están registradas, estimadas y asignadas.
IDPE5 — Definición, comunicación y maquetado
El equipo de implementación define con exactitud cómo se abordará cada tarea. Esto incluye:
- Dominio: se modelan las entidades del sistema y sus relaciones (diagramas de entidad-relación, diagramas de clases, etc.).
- Infraestructura: se detallan los requisitos del entorno que alojará el sistema.
- Sistemas: se definen las bases de datos, APIs y demás componentes a desarrollar.
- Interfaz: se diseña la experiencia de usuario mediante maquetas o prototipos de baja o media fidelidad.
Los diferentes roles se comunican activamente durante esta fase para no divergir en sus definiciones. Las maquetas permiten validar con el cliente casos de uso concretos antes de invertir tiempo en código, lo que reduce el coste de los cambios en fases posteriores.
Condiciones de salida: el dominio está modelado, las maquetas principales están validadas con el cliente y todos los roles tienen una definición técnica compartida y alineada.
IDPE6 — Corroboración
Antes de comenzar la implementación, se verifica con todos los roles que el resultado esperado está correctamente definido y que no existen conflictos entre los diferentes ámbitos que conformarán el producto. Es el último punto en el que los cambios tienen un coste bajo.
Condiciones de salida: todos los participantes del equipo han revisado y aprobado la definición. No existen ambigüedades ni contradicciones entre los diferentes ámbitos.
IDPE7 — Entorno e infraestructura
Se configura el entorno necesario para soportar la solución y facilitar el desarrollo y el despliegue. Esto incluye el aprovisionamiento de servidores y máquinas, la configuración de los entornos de desarrollo, preproducción y producción, y la puesta en marcha de las herramientas de control de versiones, integración continua y demás sistemas de soporte al equipo.
Condiciones de salida: los entornos están operativos y el equipo puede comenzar a desarrollar y desplegar sin fricciones.
IDPE8 — Implementación
Se ejecutan las tareas definidas apoyándose en el material generado en los pasos anteriores. Esto incluye escribir código en los lenguajes y tecnologías acordados, implementar los esquemas de bases de datos, integrar servicios externos y configurar aspectos operativos como copias de seguridad o políticas de acceso.
Durante esta fase se generan versiones sucesivas del producto que permiten verificar progresivamente el resultado. Se recomienda trabajar en ciclos cortos que faciliten la detección temprana de desviaciones respecto a la definición.
Condiciones de salida: todas las tareas del alcance están implementadas y desplegadas en el entorno de preproducción.
IDPE9 — Alineación y revisión
Con el producto implementado en preproducción, se realizan revisiones internas para verificar que el resultado es correcto, funciona según lo definido y no introduce regresiones. Los diferentes roles validan su ámbito: el equipo de QA ejecuta las pruebas definidas, el equipo de UX revisa la interfaz y el flujo de usuario, y el equipo de implementación corrige los problemas detectados.
Si se identifican desviaciones significativas respecto a la definición, puede ser necesario retroceder a pasos anteriores.
Condiciones de salida: el producto supera las pruebas internas y está listo para ser presentado al cliente.
DPE10 — Entrega
El producto se despliega en producción y se entrega al cliente. Se considera que cubre las necesidades mínimas acordadas en el alcance y que el cliente está satisfecho con esta primera versión. Cualquier funcionalidad adicional o mejora identificada durante el proceso queda registrada para planificarse en el siguiente ciclo.
Condiciones de salida: el producto está en producción y el cliente lo ha validado.
Bloque II: EM — Extensión y Mantenimiento
Este segundo bloque se activa al recibir nuevas necesidades sobre un producto ya existente: nuevas funcionalidades, ajustes sobre casos de uso no contemplados en la primera entrega o tareas de mantenimiento correctivo. El ciclo sigue exactamente los mismos pasos que el Bloque I, pero al partir de un producto ya construido y un equipo que ya conoce el dominio, cada paso se completa con mayor agilidad.
La principal diferencia respecto al Bloque I es que cualquier cambio debe evaluarse en el contexto de lo ya existente: cómo encaja con la arquitectura actual, qué riesgos introduce y qué partes del sistema pueden verse afectadas.
GEM1-4 — Recepción, viabilidad, estimación y planificación
Se reciben ideas o sugerencias de mejora, nuevos requisitos o casos de uso no contemplados en la versión anterior. El proceso sigue los mismos pasos que en el Bloque I: se define el alcance junto al cliente, se debate la viabilidad técnica con el equipo, se genera una oferta y se planifican las tareas concretas a realizar.
En este bloque cobran especial importancia dos consideraciones adicionales. La primera es la compatibilidad: cómo encajarán los cambios con lo ya implementado y qué partes del sistema pueden verse afectadas. La segunda es la deuda técnica: si durante el Bloque I se tomaron decisiones provisionales o se identificaron mejoras pendientes, este es el momento de valorar si es un buen momento para abordarlas junto a las nuevas funcionalidades o si no ofrecen un beneficio objetivo.
Condiciones de salida: el alcance del nuevo ciclo está acordado con el cliente, las tareas están registradas, estimadas y asignadas, y el equipo ha identificado los riesgos de integración con el producto existente.
IEM5-9 — Definición, modelado e implementación
Se pone en marcha la ejecución teniendo siempre en cuenta el producto existente. La definición técnica parte del dominio ya modelado, que puede ampliarse o modificarse, y la implementación aprovecha las facilidades previstas durante el Bloque I para soportar la escalabilidad del sistema.
Es importante verificar que los cambios no introducen regresiones en las funcionalidades ya entregadas, por lo que las pruebas deben cubrir tanto las nuevas implementaciones como las partes del sistema que puedan haberse visto afectadas.
Condiciones de salida: las nuevas funcionalidades están implementadas y desplegadas en preproducción, las pruebas de regresión han sido superadas y el sistema mantiene la estabilidad del producto anterior.
CEM10 — Entrega
El producto actualizado se despliega en producción y se entrega al cliente siguiendo el mismo proceso que en el Bloque I. Se valida que las nuevas funcionalidades cumplen el alcance acordado y que las ya existentes no se han visto afectadas negativamente.
Condiciones de salida: el producto actualizado está en producción, el cliente ha validado los cambios y el bloque EM queda cerrado.
Conclusión
Este marco de trabajo es, como su propio prefacio advierte, una guía hecha para romperse. No pretende ser exhaustivo ni aplicable al pie de la letra en todos los contextos. Su valor está en tener un punto de partida común, algo a lo que referirse cuando el equipo no sabe cómo avanzar o cuando hay que justificar por qué un paso no puede saltarse.
Quedan muchas cosas por desarrollar: cómo aplicar este ciclo en entornos ágiles, cómo adaptarlo a proyectos en solitario, o cómo integrar herramientas de IA de forma coherente en cada fase. Espero ir completando esas piezas en futuros artículos, y que este sirva mientras tanto como base suficiente para arrancar.
Agradecimientos
Este marco no habría existido sin el gran equipo con el que tuve la suerte de trabajar en Enbi, donde inicié realmente mi carrera profesional como desarrollador de software. Fue allí donde me enfrenté a proyectos reales con sus plazos, sus imprevistos y sus decisiones difíciles, y donde entendí que desarrollar software va mucho más allá de escribir código: que comunicarse bien es tan importante como implementar bien y que trabajar en equipo exige una honestidad y una claridad que no se aprenden leyendo sino practicando.
Gracias a todos los que formaron parte de esa etapa de mi carrera profesional.