Tema 2. Ingeniería del software

Currículo: esta unidad cubre parte de los saberes básicos del Bloque A – Desarrollo de Software (TICO.2.A.2) correspondiente a 2º Bachillerato. Además, se evalúan los criterios que puedes encontrar al final de esta página.

Tabla de contenidos

La Ingeniería de Software es un campo enorme que combina elementos de la informática y la ingeniería para el desarrollo de software. Esta disciplina se ocupa de los principios y prácticas para diseñar, desarrollar, mantener y probar software de manera eficiente y de alta calidad.

Al haber finalizado el Tema 1 sobre Programación, ya tenéis una base sólida sobre cómo se construyen y estructuran los programas informáticos, así como una comprensión de los lenguajes de programación, estructuras de control y orientación a objetos. Estos conocimientos son fundamentales para adentrarse en el mundo de la Ingeniería de Software.

La Ingeniería de Software no se limita solo a escribir código, de hecho, la implementación de los programas es sólo una pequeña parte de todo el proceso. Incluye un conjunto de actividades, metodologías y prácticas que abarcan desde la concepción de una idea de software hasta su materialización y mantenimiento. Se centra en métodos sistemáticos y cuantificables para la creación de software, así como en su gestión y desarrollo.

Pongámonos en el caso, por ejemplo, de la creación de una aplicación móvil para una empresa de transporte público en Huelva. El proceso comienza con la identificación de las necesidades de los usuarios y de la empresa: ¿qué funciones debería tener la app? ¿Cómo puede mejorar la experiencia de viaje de los usuarios? A partir de aquí, se aplican metodologías de desarrollo para planificar y organizar el trabajo, se emplean entornos de desarrollo integrado para facilitar la codificación, y se sigue un ciclo de vida de software para guiar todas las fases del proyecto, desde el análisis inicial hasta las pruebas finales y su lanzamiento. Durante el proceso, se utiliza el control de versiones para gestionar los cambios en el código fuente y se fomenta el trabajo en equipo y la mejora continua para optimizar el producto final.

Esta aplicación no solo facilitaría la vida de los ciudadanos, proporcionando horarios en tiempo real y rutas optimizadas, sino que también sería un ejemplo tangible de cómo la Ingeniería de Software aplica principios y prácticas metodológicas para convertir una idea en una solución tecnológica concreta y útil. 

Con estos fundamentos, estaréis preparados para adentraros en cada uno de los aspectos específicos de la Ingeniería de Software que exploraremos en los próximos temas.

2.1 Metodologías de desarrollo.

La Ingeniería de Software, como hemos visto, es una disciplina que no solo se enfoca en escribir código, sino que también implica una serie de procesos y prácticas que garantizan la creación de un software de calidad. Un aspecto clave de este proceso son las metodologías de desarrollo, que proporcionan un marco de trabajo estructurado para la creación de software. Estas metodologías son muy importantes para organizar y controlar el proceso de desarrollo, garantizando que el producto final cumpla con los requisitos y expectativas del cliente.

Las metodologías de desarrollo de software se pueden clasificar en dos grandes grupos: tradicionales y ágiles.

2.1.1. Metodologías tradicionales

Las metodologías tradicionales de desarrollo de software representan un enfoque estructurado y secuencial para la creación de sistemas informáticos. Estas metodologías se caracterizan por su enfoque riguroso y lineal, donde cada fase del desarrollo del software se completa antes de pasar a la siguiente. El proceso es sistemático y predecible, con énfasis en la planificación detallada y la documentación exhaustiva desde las primeras etapas del proyecto.

En este marco, el alcance del proyecto, los requisitos, los tiempos y los costes se definen en la fase inicial y generalmente permanecen fijos a lo largo del desarrollo. Este enfoque es especialmente efectivo en entornos donde los requisitos son bien conocidos y poco propensos a cambiar, y también donde un control exhaustivo y una documentación detallada son fundamentales. Las metodologías tradicionales priorizan la claridad y la previsibilidad, buscando minimizar los riesgos a través de una planificación y ejecución cuidadosas.

Estas son dos de las principales metodologías tradicionales:

  • Modelo en Cascada: este es el enfoque más clásico, donde el proceso de desarrollo se ve como una secuencia lineal de etapas: análisis de requisitos, diseño, implementación, pruebas, despliegue y mantenimiento. Cada etapa debe completarse antes de pasar a la siguiente.

Ejemplo: desarrollo de un sistema de información turística para tu ciudad. Este proyecto podría seguir un proceso lineal: primero, recopilación de requisitos sobre los puntos de interés turístico, después el diseño de la interfaz y la arquitectura del sistema, seguido por la programación, las pruebas y, finalmente, el lanzamiento. Este modelo es adecuado para proyectos con requisitos bien definidos y poco cambio esperado.

  • Modelo en V: similar al modelo en cascada, pero con un énfasis más fuerte en las pruebas en cada etapa del desarrollo. Este modelo destaca la importancia de la verificación y validación durante todo el proceso de desarrollo.

Ejemplo: creación de un software de gestión para una biblioteca local. En cada fase del desarrollo, como el diseño de la interfaz de usuario o el sistema de búsqueda de libros, se planifican pruebas paralelas para asegurar que cada elemento funcione correctamente antes de avanzar. Esto es crucial en sistemas donde el fallo en una etapa inicial puede ser crítico.

2.1.2. Metodologías ágiles

Las metodologías ágiles, en contraste, adoptan un enfoque más flexible y adaptativo para el desarrollo de software. Estas metodologías se centran en la capacidad de respuesta a los cambios y en la entrega rápida de productos funcionales. En lugar de seguir un plan detallado y fijo, las metodologías ágiles promueven la iteración, la colaboración constante con el cliente, y la adaptabilidad a lo largo de todo el proyecto.

Este enfoque se basa en la idea de que los requisitos y soluciones evolucionan a través de la colaboración entre equipos auto organizados y sus usuarios finales. Las metodologías ágiles enfatizan la importancia de la entrega continua de partes funcionales del software, permitiendo ajustes frecuentes en función de la retroalimentación y los cambios en las necesidades del cliente. Este enfoque es ideal en proyectos dinámicos con requisitos inciertos o en constante evolución, donde la flexibilidad y la capacidad de adaptación rápida son esenciales para el éxito del proyecto.

Estas son tres de las metodologías ágiles más populares:

  • Desarrollo Ágil de Software: en contraste con los métodos tradicionales, el desarrollo ágil es más flexible y adaptable. Se enfoca en la entrega rápida y continua de software funcional, con énfasis en la colaboración entre equipos multifuncionales y clientes.

Ejemplo: diseño de una app móvil para el ayuntamiento de tu ciudad, que permita a los ciudadanos reportar problemas urbanos. Este proyecto se beneficiaría de la flexibilidad del desarrollo ágil, ya que las necesidades y feedback de los usuarios pueden cambiar rápidamente. Los desarrolladores trabajan en versiones iterativas, ajustándose continuamente a las necesidades de los usuarios.

  • Scrum: una de las metodologías ágiles más populares. Scrum divide el proyecto en pequeños fragmentos de trabajo llamados sprints, cada uno de los cuales entrega una parte del software. Es altamente colaborativo y adaptable a cambios rápidos.

Explicación clara de cómo funciona esta metodología.

Ejercicio 2.1 – In Code We Trust

El Club de Ciclismo de Aljaraque le ha encargado a tu empresa llamada In Code We trust, que desarrolle una pequeña tienda online para vender productos del club con la finalidad de autofinanciarse. Se han reunido Javi (por parte del club que será quién traslade sus necesidades y quien probará la aplicación) y Julia (por parte de tu empresa, que será la única que conozca todos los detalles del proyecto). Cuando Julia lo tiene todo claro mantiene una reunión con Andrea y le traslada todas las necesidades del nuevo proyecto que acaba de entrar, como por ejemplo:

  • La tienda debe destacar en la parte superior los 5 artículos más vendidos del último mes.
  • La tienda debe mostrar un enlace para ver todas las ofertas y promociones vigentes actualmente.
  • Para comprar los usuarios deben iniciar sesión y estar registrados previamente.
  • El pago debe hacerse siempre con tarjeta en el menor número de pasos posible.
  • Los usuarios deben poder devolver un producto con un único clic.
  • ….

Andrea analiza toda la información y monta un enorme mural en la pared del despacho con todas las funcionalidades que debe tener la aplicación. Luego se reúne con Laura y establecen un plan de trabajo para las dos próximas semanas (a este plan le llaman T1): harán el registro e inicio de sesión del usuario y dejarán lista el área privada del usuario para que se puedan listar productos comprados y hacer devoluciones.

Al día siguiente, al inicio de la jornada laboral, se reúnen Andrea y Laura con dos programadores que se llaman Fran y Silvia. Laura les explica cómo van a trabajar. Fran detecta una necesidad que Laura le resuelve, y cada uno vuelve a su puesto de trabajo. Dos días más tarde Javi le traslada la Julia el deseo de que el registro de usuario se pueda hacer con un único clic usando cuentas de correo de Google. Así que, al día siguiente, se vuelven a reunir Andrea, Laura, Fran y Silvia ante la necesidad que tiene Andrea de trasladarles las novedades que Julia le contó el día anterior. Silvia pregunta cómo modificar su plan de trabajo para hoy, para acomodar la nueva restricción y Laura le resuelve la duda.

Sabiendo todo lo anterior rellena la siguiente tabla justificando en cada caso tu respuesta:

¿Quién(es) es el Customer?
¿Quién(es) es el SCRUM Master?
¿Quién(es) es el Product Owner?
¿Quién(es) es el User?
¿Quién(es) forma(n) parte del Equipo de Desarrollo?
¿Quién(es) forma(n) parte del SCRUM Team?
Identifica qué están usando como Backlog
Identifica tres historias de usuario
Identifica un sprint
Identifica un Daily SCRUM 

 

  • Extreme Programming (XP): esta metodología enfatiza la calidad técnica del software, con prácticas como la programación en parejas, desarrollo basado en pruebas, y refactorización continua del código.

Por ejemplo: desarrollo de un portal educativo interactivo para un instituto. Dado que este proyecto involucra múltiples partes interesadas (profesores, estudiantes, administración), el XP sería ideal para garantizar una alta calidad y adaptabilidad. Los desarrolladores trabajan en estrecha colaboración, con revisiones continuas y adaptaciones basadas en las pruebas y feedback de los usuarios finales.

Veamos ahora un ejemplo práctico de todo el proceso de desarrollo, utilizando el modelo tradicional -que mejor entienden los que comienzan a recorrer este camino de la ingeniería del software-: el modelo en cascada.

Una buena mañana, recibimos el siguiente correo electrónico de un potencial cliente:
De: Restaurante Delicias Andaluzas <gerencia@fakerestaurant.es>
Asunto: Desarrollo de aplicación para Restaurante
Estimado equipo de desarrollo,
Estamos interesados en desarrollar una aplicación móvil para nuestro restaurante, Delicias Andaluzas. Queremos que nuestros clientes puedan ver el menú, realizar pedidos, reservar mesas y dejar reseñas. También necesitamos una sección para eventos especiales y ofertas.
Esperamos vuestra propuesta.
Saludos,
Gerente de Delicias Andaluzas

Veamos cómo sería un hipotético proceso completo. Debes entender que hemos simplificado mucho todos los procesos para que sean entendibles. Esto en la realidad profesional, es bastante más complejo y detallado.

Análisis de Requisitos

Esta es la primera fase del modelo en cascada. En esta etapa, identificamos y documentamos lo que el cliente necesita. Para nuestro ejemplo, los requisitos incluirían la capacidad de ver menús, realizar pedidos, reservar mesas, dejar reseñas, y mostrar eventos y ofertas. Pero, qué entiende el cliente por “ver menús” o “realizar pedidos”, ¿tiene un modelo en mente?¿Quiere copiar el funcionamiento de otra app que ha visto?¿Puede un cliente reservar todas las mesas?¿Puede realizar una misma reserva para varias horas distintas?¿El sistema permitirá dar de baja un elemento de un menú días concretos por falta de género?¿Los precios son fijos o se deben poder modificar al vuelo de manera rápida? Todas estas preguntas, y cientos de ellas más, no han quedado resueltas con el mensaje del cliente. De hecho, podrías reunirte varias veces con el cliente y descubrir que no ha pensado en muchas de las situaciones que podrían darse y eres tú quien debe proponerle alternativas. Esta fase es la más importante de todas, porque es la que determinará qué es lo que debe hacer la aplicación y cómo debe hacerlo. Debe quedar todo por escrito y con el visto bueno del cliente.

Diseño

Segunda etapa del modelo en cascada. Aquí, se crea un diseño detallado de la aplicación basado en los requisitos recogidos. Decidimos cómo se verá la interfaz de usuario, cómo se organizará la información en la aplicación, y cómo se integrarán las diferentes funcionalidades (menús, pedidos, reservas, etc.). Es el equivalente a los planos de un arquitecto.

Implementación

Tercera etapa del proceso. En esta fase, los programadores escriben el código para crear la aplicación. Se desarrolla la aplicación siguiendo el diseño establecido, implementando todas las funcionalidades requeridas.

Pruebas

Cuarta etapa del modelo en cascada. Después de implementar la aplicación, se realizan pruebas para asegurar que todo funciona correctamente. Se comprueba que la app cumple con los requisitos del cliente y que no hay errores o inconsistencias.

Despliegue

Quinta etapa del proceso. Una vez que la aplicación ha sido probada y se confirma que está lista, se procede a su lanzamiento o despliegue. Esto significa que la aplicación se pone a disposición de los usuarios, en este caso, los clientes del restaurante.

Mantenimiento

Última etapa del modelo en cascada. Después del despliegue, la aplicación requiere mantenimiento continuo. Esto puede incluir la actualización de la aplicación con nuevas funciones, la corrección de errores que se encuentren, y la adaptación a nuevas necesidades del restaurante o los usuarios.

2.2.3. La importancia de la especificación de requisitos

La especificación de requisitos del sistema (ERS) es un trabajo tan importante, que lo condiciona todo, por eso hay que hacer un trabajo minucioso y detallado. Ten en cuenta que en esa especificación es donde se detalla qué hay que hacer, y por omisión, qué no hay que hacer. Es un documento que tenemos validado con el cliente que no solo marca el trabajo que debemos hacer, sino que podría ser útil para resolver cualquier disputa que pudiera surgir a la entrega del software.

Para que te hagas una idea, este es el índice de la ERS del Marco de Desarrollo de Software de la Junta de Andalucía:

Ejercicio 2.2 – Mockup

Esta es una conversación entre el gerente del Restaurante Delicias Andaluzas del ejemplos anterior y la empresa para que trabajas como ingeniero del software:

Gerente: Buenos días, estamos muy emocionados con la idea de la aplicación. Queremos asegurarnos de que nuestros clientes tengan una experiencia excelente.

Empresa: ¡Buenos días! Nos encantaría conocer más sobre lo que necesita. ¿Podría detallarnos qué espera de la función de visualización del menú?

Gerente: Claro, necesitamos que nuestros clientes vean el menú actualizado diariamente, con fotos de los platos y los precios. Además, sería genial si pudieran filtrar el menú por categorías como ‘entrantes’, ‘platos principales’, ‘postres’ y ‘bebidas’.

Empresa: Entendido. ¿Y qué me dice sobre la función de realizar pedidos?

Gerente: Queremos que los clientes puedan seleccionar platos del menú y hacer un pedido directamente desde la app. Deberían poder elegir la opción de recoger en el restaurante o de entrega a domicilio.

Empresa: Perfecto. ¿Cómo imagina la función de reserva de mesas?

Gerente: Los clientes deberían poder seleccionar la fecha, hora y número de personas para su reserva. Además, nos gustaría que pudieran ver un mapa del restaurante con la disposición de las mesas.

Empresa: Excelente, ¿y en cuanto a las reseñas?

Gerente: Después de comer, los clientes deberían recibir una notificación para valorar su experiencia y dejar un comentario en la app.

Empresa: ¿Hay algo especial que desee para la sección de eventos y ofertas?

Gerente: Sí, necesitamos actualizar esa sección semanalmente con eventos especiales, como noches de música en vivo, y promociones como descuentos en ciertos platos.

Basándote en la conversación anterior:

  1. Lee detenidamente cada uno de los detalles de la misma.
  2. Identifica y lista los requisitos específicos para cada funcionalidad de la aplicación.
  3. Considera tanto las necesidades funcionales (lo que la aplicación debe hacer) como las no funcionales (como la facilidad de uso, diseño, etc., teniendo en cuenta que se trata de una aplicación móvil).
  4. Crea un mockup de las distintas pantallas de la aplicación que diseñarías conociendo todos los requisitos anteriores. Puedes utilizar para ello cualquier aplicación que conozcas (tipo Canva o Genially) o puedes practicar descubriendo alguna de estas 5: Figma, Balsamiq, MockFlow, Wireframe, Moqups.
  5. Debes entregar, o bien un enlace público -de la herramienta de diseño que has usado- donde se puedan ver los diseños de todas las pantallas que has preparado, o bien un enlace público de un Documento de Google donde hayas insertado capturas de pantalla de cada uno de tus diseños. Tu diseño debe incluir un mínimo de 5 pantallas de la aplicación.

Un mockup es un prototipo que representa la apariencia de un producto y que sirve para obtener la aprobación de un cliente o usuario final. Por ejemplo, este es un mockup de cómo se vería una aplicación en un portátil, una tablet y un smartphone:

2.2. Entornos de desarrollo integrado

Un entorno de desarrollo integrado (IDE) es una aplicación informática que combina en un solo lugar todas las herramientas necesarias para realizar un proyecto de desarrollo de software. Ofrece una interfaz que permite escribir código, organizar grupos de texto y automatizar las tareas redundantes de programación.

Los IDE están diseñados para maximizar la productividad del programador proporcionando componentes muy unidos con interfaces de usuario similares. Los IDE presentan un único programa en el que se lleva a cabo todo el desarrollo. Generalmente, este programa suele ofrecer muchas características para la creación, modificación, compilación, implementación y depuración de software.

2.2.1. Características de un IDE

Generalmente, un IDE cuenta con las siguientes características:

  • Editor de código fuente: es la herramienta principal de un IDE, donde se escribe el código del programa. El editor suele tener funciones de auto-completado de código, resaltado de sintaxis, indentación automática, búsqueda y reemplazo, entre otras.
  • Compilador o intérprete: es la herramienta que traduce el código fuente a un lenguaje que pueda ser ejecutado por la máquina. Algunos IDE tienen un compilador o intérprete integrado, mientras que otros lo invocan externamente.
  • Depurador: es la herramienta que permite detectar y corregir errores en el código. El depurador suele permitir ejecutar el programa paso a paso, establecer puntos de interrupción, inspeccionar variables, modificar valores, entre otras funciones.
  • Constructor automático: es la herramienta que automatiza el proceso de construcción del software, es decir, la generación de los archivos ejecutables y las dependencias necesarias. El constructor suele invocar al compilador, al enlazador y a otras herramientas externas.
  • Navegador de código: es la herramienta que facilita la navegación por el código fuente, mostrando la estructura del programa, las clases, los métodos, las variables, etc. El navegador suele estar sincronizado con el editor, de modo que al seleccionar un elemento se muestra su código correspondiente.
  • Diseñador de interfaz gráfica de usuario (GUI): es la herramienta que permite crear la interfaz gráfica de usuario del programa mediante un editor visual, arrastrando y soltando componentes, estableciendo propiedades y eventos, etc. El diseñador suele generar el código necesario para crear la GUI.
  • Controlador de versiones: es la herramienta que permite gestionar las diferentes versiones del código fuente, así como las modificaciones realizadas por los desarrolladores. El controlador suele permitir crear repositorios, ramas, etiquetas, fusionar cambios, resolver conflictos, etc.
  • Otras herramientas: dependiendo del IDE, pueden incluirse otras herramientas como analizadores de código, generadores de documentación, pruebas unitarias, simuladores, emuladores, etc.

2.2.2. Los IDE más importantes

Existen muchos IDE disponibles para diferentes lenguajes de programación, plataformas y propósitos. Algunos ejemplos de IDE son:

  • Eclipse: es un IDE de código abierto y multiplataforma que soporta varios lenguajes de programación, como Java, C, C++, Python, PHP, etc. Eclipse ofrece un sistema de plugins que permite ampliar sus funcionalidades y adaptarlo a diferentes tipos de proyectos. [Sitio web oficial]
  • Visual Studio: es un IDE de Microsoft que soporta principalmente los lenguajes de programación de la plataforma .NET, como C#, Visual Basic, F#, etc. Visual Studio ofrece un entorno integrado para el desarrollo de aplicaciones de escritorio, web, móviles, juegos, etc. [Sitio web oficial]
  • NetBeans: es un IDE de código abierto y multiplataforma que soporta varios lenguajes de programación, como Java, C, C++, PHP, HTML, CSS, JavaScript, etc. NetBeans ofrece un entorno integrado para el desarrollo de aplicaciones de escritorio, web, móviles, etc. [Sitio web oficial]
  • PyCharm: es un IDE de JetBrains que soporta el lenguaje de programación Python y sus principales librerías y frameworks. PyCharm ofrece un entorno integrado para el desarrollo de aplicaciones de ciencia de datos, inteligencia artificial, web, etc. [Sitio web oficial]

2.2.3. Un IDE para todo en la práctica

PyCharm, como hemos visto, es un IDE que facilita el desarrollo de aplicaciones en Python. Un ejemplo práctico de cómo lo usamos en el desarrollo real de una aplicación, podría ser el siguiente:

Supongamos que quieres crear una aplicación web que permita a los usuarios buscar información sobre películas, actores y directores. Para ello, podrías usar PyCharm para realizar las siguientes tareas:

  1. Crear un proyecto de Django, que es un framework web de Python que te permite crear sitios web dinámicos y escalables.
  1. Escribir el código de la aplicación en el editor de código fuente de PyCharm, que te ofrece funciones de auto-completado, resaltado de sintaxis, refactorización, etc.
  1. Usar el diseñador de interfaz gráfica de usuario de PyCharm para crear las plantillas HTML que definan el aspecto de la aplicación web, arrastrando y soltando componentes, estableciendo propiedades y eventos, etc.
  1. Usar el depurador de PyCharm para detectar y corregir errores en el código, ejecutando el programa paso a paso, estableciendo puntos de interrupción, inspeccionando variables, modificando valores, etc.
  1. Usar el constructor automático de PyCharm para automatizar el proceso de construcción de la aplicación web, generando los archivos ejecutables y las dependencias necesarias.
  1. Usar el navegador de código de PyCharm para navegar por el código fuente, mostrando la estructura del programa, las clases, los métodos, las variables, etc.
  1. Usar el controlador de versiones de PyCharm para gestionar las diferentes versiones del código fuente, así como las modificaciones realizadas por los desarrolladores, creando repositorios, ramas, etiquetas, fusionando cambios, resolviendo conflictos, etc.
  1. Usar el simulador de PyCharm para probar la aplicación web en un navegador web integrado, con funciones de registro, inspección, etc.

Si quieres aprender más sobre PyCharm, aquí tienes una guía para principiantes.

2.3. Ciclo de vida del software

El ciclo de vida del software es el conjunto de actividades que se realizan desde que se concibe una idea para un software hasta que se entrega y se mantiene el producto final. El objetivo del ciclo de vida del software es asegurar que el software cumpla con los requisitos del cliente, que se desarrolle de forma eficiente y que se garantice su calidad.

El ciclo de vida del software se compone de varias etapas, que ya hemos introducido en el inicio del tema y que pueden variar según el modelo que se elija para gestionar el proyecto. Sin embargo, las etapas más comunes son las que vemos en detalle a continuación (se incluyen en cada caso, dos de las herramientas más populares que se utilizan en ellas).

  1. Planificación: en esta fase se definen los objetivos del proyecto, se establece el alcance -qué se va a hacer y qué no-, se determinan los recursos necesarios -humanos, hardware, software, presupuesto-, se identifican los riesgos -estableciendo medidas para mitigarlos- y se establece un cronograma -para poder llevar a cabo el proyecto en los tiempos previstos-. También se establece la comunicación con el cliente y se recogen sus necesidades y expectativas. Es importante que se elija el modelo de ciclo de vida más adecuado para el proyecto, ya que esto influirá en la forma en que se gestionará el proyecto.
  • Jira: ampliamente utilizada para la gestión de proyectos y seguimiento de tareas. Su punto fuerte es la capacidad para planificar, asignar y seguir el progreso del trabajo en un entorno ágil.
  • Trello: una herramienta basada en el sistema Kanban, ideal para organizar tareas y colaborar en proyectos. Su interfaz intuitiva y visual facilita la planificación y seguimiento de tareas.
  1. Análisis: en esta fase se especifican los requisitos funcionales y no funcionales del software, es decir, lo que el software debe hacer y cómo debe hacerlo. Se analiza el problema a resolver, se identifican las características y los casos de uso del software, y se documentan los requisitos. Aquí se establecen las bases para el diseño y la implementación. Es importante que se realice una buena documentación de los requisitos, ya que esto permitirá validarlos con el cliente y evitar problemas en etapas posteriores del proyecto.
  • Enterprise Architect: herramienta de modelado UML para la visualización y análisis de requisitos del sistema. Es conocida por su amplia gama de funcionalidades para el modelado y análisis de sistemas complejos.
  • Rational Rose: especializada en el modelado UML, ayuda en el análisis de requisitos y diseño del sistema. Su punto fuerte es la integración con otras herramientas y su capacidad para manejar grandes proyectos.
  1. Diseño: en esta fase se define la arquitectura del software, es decir, cómo se va a construir. Se diseñan los componentes, las interfaces, los datos, los algoritmos y los métodos que formarán el software. Se documenta el diseño y se valida con el cliente. Es importante que se realice una buena documentación del diseño, ya que tras validarlo con el cliente, ambas partes tendrán una idea común de lo que se espera. De esta manera, se evitan numerosos problemas en etapas posteriores del proyecto.
  • Adobe XD: utilizada para diseñar interfaces de usuario y experiencias de usuario (UI/UX). Destaca por su facilidad de uso y herramientas colaborativas.
  • Axure RP: herramienta para crear prototipos y wireframes de alta fidelidad. Su fuerza radica en la capacidad para simular interacciones complejas y generar prototipos interactivos.
  1. Implementación: en esta fase se escribe el código fuente del software, usando el lenguaje de programación y las herramientas elegidas. Se siguen las normas de codificación y se aplican las técnicas de reutilización de código. Se generan los archivos ejecutables y las dependencias del software. La implementación es una etapa clave del ciclo de vida del software, ya que permite transformar el diseño en código fuente. Es importante que se realice una buena documentación del código fuente, ya que esto permitirá entender el funcionamiento del software y facilitar su mantenimiento. Piensa que la persona que codifique una funcionalidad concreta del software es posible que ya no esté en la empresa cuando se detecte un error. Incluso siendo la misma persona, tras miles de líneas de código desarrolladas es muy probable que no recuerde por qué tomó las decisiones que tomó en su día.
  • Visual Studio: un IDE completo de Microsoft que soporta múltiples lenguajes de programación. Es apreciado por su integración con .NET Framework y herramientas avanzadas de desarrollo.
  • Eclipse: un IDE de código abierto ampliamente utilizado, conocido por su flexibilidad y soporte para múltiples lenguajes y plataformas.
  1. Pruebas: las pruebas son una etapa fundamental del ciclo de vida del software, ya que permiten verificar y validar el software. En esta fase se realizan diferentes tipos de pruebas, como pruebas unitarias, de integración, de sistema, de aceptación, etc. Las pruebas unitarias se enfocan en verificar el correcto funcionamiento de cada unidad de código. Las pruebas de integración se enfocan en verificar que los diferentes componentes del software funcionen juntos correctamente. Las pruebas de sistema se enfocan en verificar que el software cumple globalmente con el objetivo general buscado. Las pruebas de aceptación se enfocan en verificar que el software cumple con los criterios de aceptación del cliente. Es importante que se realicen pruebas exhaustivas para detectar y corregir los errores antes de que el software se entregue al cliente.
  • Selenium: una herramienta para pruebas automatizadas de aplicaciones web. Su capacidad para automatizar navegadores web y probar en diferentes entornos es su punto fuerte.
  • JUnit: marco de trabajo para pruebas unitarias en aplicaciones Java. Destaca por su sencillez y eficacia en la ejecución de pruebas repetitivas y automatizadas. Su equivalente para Python sería Pytest.
  1. Despliegue: el despliegue es una etapa crítica del ciclo de vida del software, ya que permite entregar el software al cliente. En esta fase se instala y se pone en funcionamiento el software en el entorno del cliente. Se realizan las configuraciones necesarias y se entregan los manuales de usuario y de instalación. Es importante que se realice una buena planificación del despliegue para evitar problemas en la instalación y configuración del software. Además, se capacita al cliente y se obtiene su retroalimentación.
  • Docker: plataforma para desarrollar, enviar y ejecutar aplicaciones en contenedores. Su fortaleza es la portabilidad y la consistencia entre entornos de desarrollo y producción.
  • Jenkins: herramienta de integración continua y despliegue continuo. Es muy valorada por su capacidad para automatizar diferentes etapas del proceso de desarrollo y despliegue.
  1. Mantenimiento: es la etapa donde se proporciona soporte y asistencia al cliente durante el uso del software. Se realizan las actualizaciones, las correcciones y las mejoras que el software requiera. Se monitoriza el rendimiento de la aplicación. Es importante que se realice una buena gestión del mantenimiento para garantizar la satisfacción del cliente y mantener la calidad del software en unos estándares aceptables.
  • Git: sistema de control de versiones para seguimiento de cambios en el código fuente durante el desarrollo de software. Su eficiencia en la gestión de ramas y su flexibilidad son puntos destacados.
  • Redmine: una herramienta de gestión de proyectos y seguimiento de errores. Es conocida por su capacidad para manejar múltiples proyectos y su sistema integrado de seguimiento de problemas.

2.3.1. Los casos de uso

Una de las maneras más intuitivas que existen para conocer qué espera el cliente de nuestra aplicación, es conocer la lista de casos de uso, que se identifican en la fase de análisis. Pero, ¿qué es un caso de uso?

Un caso de uso en ingeniería del software es una descripción detallada de cómo un usuario o sistema interactúa con una aplicación para lograr un objetivo específico. Es una manera de capturar los requisitos funcionales de un sistema. Los casos de uso describen el comportamiento del sistema desde el punto de vista del usuario, lo que ayuda a entender el software desde la perspectiva de quienes lo usarán.

En esencia, un caso de uso define quién (actor) hace qué (interacción) con el sistema, para qué fin (objetivo). Cada caso de uso se enfoca en describir una secuencia de eventos que proporciona un resultado observable y valioso para un actor particular.

Por ejemplo, supongamos que estamos desarrollando un sistema de gestión de biblioteca. Uno de los casos de uso podría ser “Prestar un libro”. Aquí está cómo podríamos describirlo:
Título: prestar un libro.
Actor: usuario de la biblioteca.
Objetivo: el actor desea tomar prestado un libro de la biblioteca.
Flujo de eventos:

  1. Inicio: el usuario accede al sistema de la biblioteca con su identificación de miembro.
  2. Búsqueda de libro: el usuario busca un libro específico utilizando la función de búsqueda del sistema.
  3. Selección del libro: una vez encontrado el libro, el usuario selecciona la opción “Prestar libro”.
  4. Verificación de disponibilidad: El sistema verifica si el libro está disponible para préstamo.
  5. Confirmación del préstamo:
    1. Si el libro está disponible, el sistema registra el préstamo asociándolo a la cuenta del usuario y establece la fecha de devolución.
    2. Si el libro no está disponible, se informa al usuario y se le ofrecen opciones alternativas (como reservar el libro o elegir otro).
  6. Finalización: el usuario recibe una confirmación del préstamo -por correo electrónico- con los detalles del mismo, incluyendo la fecha de devolución.

Precondiciones

  • El usuario debe estar registrado en el sistema de la biblioteca.
  • El usuario debe tener una activa.

Postcondiciones

  • El libro está marcado como prestado.
  • El libro no está disponible para otros usuarios hasta su devolución.

Este caso de uso detalla cómo un usuario interactúa con el sistema de la biblioteca para lograr el objetivo de tomar prestado un libro. Proporciona una visión clara de las funcionalidades necesarias en el sistema y cómo deben interactuar con el usuario. Los casos de uso como este son valiosos para entender las necesidades de los usuarios y diseñar un sistema que las satisfaga eficazmente.

Ejercicio 2.3 – Casos de uso

Escribe un caso de uso para cada una de las siguientes situaciones, asegurándote de que incluyes cada una de las 6 partes que la componen -título, actores, objetivo, flujo de eventos, precondiciones y postcondiciones-.

  1. Una empresa está desarrollando un sistema de reservas online para hoteles. Escribe un caso de uso detallado para el proceso de “Reservar una habitación”. Incluye pasos desde la búsqueda de hoteles hasta la confirmación de la reserva.
  2. Una empresa de moda está creando una plataforma de comercio electrónico para vender ropa. Desarrolla un caso de uso para el proceso de “Realizar una Compra”. Describe el proceso de selección de artículos, añadirlos al carrito, proceder al pago y recibir la confirmación del pedido.
  3. Una startup está desarrollando una aplicación móvil para pedir y entregar comida de restaurantes locales. Escribe un caso de uso para el proceso de “Pedir una entrega de comida”. Incluye la selección del restaurante, elección del menú, pago y seguimiento del pedido.
  4. Una empresa local está desarrollando una aplicación móvil para solicitar servicios de taxi. Escribe un caso de uso detallado para el proceso de “Solicitar un taxi”. El caso de uso debe incluir los pasos desde que el usuario abre la aplicación, introduce su ubicación, selecciona el destino, elige el tipo de vehículo, confirma el viaje, recibe detalles del conductor asignado y finalmente el taxi llega a la ubicación del usuario.
  5. Una compañía está desarrollando un sistema online para la gestión y venta de entradas para eventos como conciertos, obras de teatro y eventos deportivos. Escribe un caso de uso detallado para el proceso de “Comprar entradas para un evento”. El caso de uso debe abarcar desde la búsqueda del evento por parte del usuario, selección de asientos, proceso de pago, hasta la recepción de la confirmación y las entradas digitales.

2.4. Control de versiones

El control de versiones en la ingeniería del software es fundamental para la gestión eficiente de los cambios que se producen en el código fuente de un programa a lo largo del tiempo. Esta práctica permite a los equipos de desarrollo rastrear y gestionar las modificaciones realizadas en el código, facilitando la colaboración entre múltiples desarrolladores y la recuperación de versiones anteriores del software en caso de necesidad.

2.4.1. Características principales

  • Gestión de cambios: el control de versiones permite a los desarrolladores trabajar simultáneamente en diferentes partes de un proyecto sin interferir entre sí. Cada cambio en el código se registra con detalles como el autor del cambio, la fecha y una descripción de la modificación.
  • Colaboración en equipo: facilita la colaboración entre múltiples desarrolladores, incluso cuando están geográficamente dispersos. Los equipos pueden fusionar sus cambios en un repositorio común, resolviendo posibles conflictos entre diferentes versiones del código.
  • Seguimiento del historial: permite mantener un historial completo de todas las modificaciones, facilitando la comprensión de la evolución del proyecto y la identificación de cuándo y por qué se introdujeron ciertos cambios.
  • Recuperación de versiones: en caso de errores o problemas, los desarrolladores pueden revertir el código a una versión anterior, garantizando así la estabilidad y funcionalidad del software.

2.4.2. Control de versiones en funcionamiento

Supongamos que un grupo de alumnos está trabajando en el desarrollo de una aplicación web para un proyecto académico. Deciden utilizar Git, la herramienta de control de versiones por excelencia, para gestionar su código.

Inicio del proyecto

Inicialmente, crean un repositorio en GitHub y comienzan a trabajar en la base del proyecto. Cada estudiante trabaja en características diferentes: uno en la interfaz de usuario, otro en la base de datos, y un tercero en la lógica de negocio.

Registrar y publicar 

A medida que avanzan, van haciendo registros de sus cambios con mensajes descriptivos y suben estos cambios al repositorio remoto en GitHub usando publicar. Esto permite que todos tengan acceso a los últimos cambios.

Resolución de conflictos

En un momento dado, dos alumnos editan la misma línea de código. Git marca esto como un conflicto. Juntos, revisan los cambios, deciden cuál versión conservar y resuelven el conflicto.

Revisión del historial

Después de algunas semanas, se dan cuenta de que una funcionalidad implementada anteriormente ya no funciona correctamente. Utilizan el historial de Git para identificar el cambio que causó el problema y lo corrigen.

Colaboración y revisión de código

Además, utilizan las funcionalidades de revisión de código de GitHub para revisar y comentar el trabajo de sus compañeros antes de fusionarlo con la rama principal.

El uso de tareas comunes para el control de versiones con Git y GitHub, que hemos ilustrado, es fundamental en el desarrollo de software, permitiendo una colaboración eficaz, un seguimiento detallado de los cambios y la capacidad de resolver errores de manera efectiva.

Esto que hemos visto es sólo una pequeñísima muestra conceptual de lo que puede hacerse con estas dos herramientas, pero ahondemos un poco más en su parte práctica.

2.4.3. Introducción a Git

Git es el sistema de control de versiones más utilizado en la ingeniería de software, con independencia del tamaño del proyecto. Su incuestionable liderazgo se debe a factores tan importantes como:

  • Distribuido: esto significa que cada desarrollador tiene una copia local completa del repositorio, incluyendo todo el historial de cambios. Esta característica ofrece varias ventajas, como la capacidad de trabajar de manera desconectada del servidor central y la seguridad adicional de tener múltiples copias del repositorio.
  • Rendimiento: Git es conocido por su alta velocidad y eficiencia. Las operaciones principales son más rápidas en comparación con otros sistemas. Esto es especialmente útil en proyectos grandes con miles de archivos y un largo historial de cambios.
  • Flexibilidad en la gestión de ramas: Git proporciona un manejo de ramas muy potente y flexible, lo que facilita el desarrollo paralelo. Las ramas en Git son ligeras y fáciles de crear y fusionar, lo que anima a los desarrolladores a utilizar ramas para experimentar con nuevas características o para aislar trabajos.
  • Seguridad: Git utiliza una estructura de datos llamada “directed acyclic graph” (DAG), que garantiza la integridad del historial de versiones. Cada commit en Git se identifica a través de una suma de verificación SHA-1, lo que asegura que el contenido del repositorio no pueda ser alterado sin que Git lo detecte.
  • Fuerte comunidad: Git tiene una gran comunidad de usuarios y desarrolladores, lo que ha llevado a una amplia variedad de recursos de aprendizaje, herramientas de terceros, y una robusta red de soporte. Además, plataformas como GitHub y GitLab han fomentado aún más su adopción, proporcionando herramientas de colaboración y hospedaje para proyectos basados en Git.
  • Compatibilidad: Git es compatible con múltiples sistemas operativos y plataformas, haciéndolo accesible para una amplia gama de usuarios. Su naturaleza de código abierto también significa que se puede integrar y modificar para satisfacer necesidades específicas.

A continuación, se explican algunos de los conceptos básicos de Git de forma sencilla.

  • Repositorio (Repository): es como una carpeta para tu proyecto. Un repositorio de Git contiene todos los archivos de tu proyecto y el historial de todas las modificaciones realizadas a esos archivos.
  • Commit: un commit es como una instantánea de tu proyecto en un momento determinado. Cuando haces cambios en los archivos de tu proyecto y estás satisfecho con esos cambios, haces un commit para registrar esos cambios en el historial de Git. Cada commit tiene un mensaje asociado que describe qué cambios se han realizado. Para hacer un commit tan solo debes lanzar la orden git commit
  • Push: después de realizar uno o varios commits en tu repositorio local, puedes “empujar” estos cambios al repositorio remoto (por ejemplo, en GitHub) para que otros puedan verlos o colaborar. El comando push envía tus commits al repositorio remoto. Para actualizar el repositorio remoto con tus cambios, lanzas la orden git push
  • Branch (Rama): una rama en Git es como una nueva línea de desarrollo independiente. Puedes crear una rama para trabajar en nuevas características o cambios sin afectar la rama principal (generalmente llamada master o main). Esto te permite experimentar y hacer cambios en un entorno aislado. Para crear una rama nueva llamada nuevaRama, ejecutas git branch nuevaRama.
  • Checkout: este comando se utiliza para cambiar entre diferentes ramas en tu repositorio. Si quieres trabajar en una rama diferente, usas checkout para cambiar a esa rama. Para situarte en esa rama y poder trabajar en ella, hacemos git checkout nuevaRama
  • Merge (Fusión): cuando terminas de trabajar en una rama y estás satisfecho con los cambios, puedes fusionar esos cambios en tu rama principal o en otra rama. El proceso de merge toma los cambios de una rama y los aplica a otra. Si hacemos git merge, estamos fusionando la rama en la que estamos con la rama principal. Si queremos que la fusión se haga con otra rama, simplemente añadimos su nombre al final: git merge nuevaRama
  • Rebase: es una manera de integrar cambios de una rama a otra. A diferencia de la fusión, rebase reescribe la historia del proyecto al mover o combinar una secuencia de commits a una nueva base de commit. Se utiliza para mantener un historial de proyecto más limpio. 

Este gráfico define a la perfección los principales comandos que usamos en cada fase de nuestro desarrollo diario:

Toda la parte situada a la izquierda de la barra negra, está en nuestro propio equipo. Cuando usas Git, hay tres “espacios” principales en tu equipo que son importantes entender: el área de trabajo (workspace), el área de preparación (staging area) y el repositorio local (local repository). Aquí te explico cada uno de forma sencilla:

  1. Workspace (Área de Trabajo): es donde realizas todos tus cambios en los archivos, tu directorio de trabajo local diario en tu equipo. Aquí puedes crear, editar y eliminar archivos. 
  1. Staging Area (Área de Preparación): la staging area, a veces llamada “index”, es una especie de área intermedia entre tu workspace y tu repositorio local. Cuando haces cambios en tu workspace y estás satisfecho con ellos, los “añades” (usando el comando git add) a la staging area. De esta manera preparamos y organizamos tus cambios antes de confirmarlos (hacer un commit). Te permite controlar exactamente qué cambios quieres incluir en tu próximo commit, lo que te proporciona una gran flexibilidad y precisión en el manejo de tu código.
  1. Local Repository (Repositorio Local): es donde Git guarda los snapshots o instantáneas de tu proyecto, es decir, tus commits. Después de agregar los cambios a la staging area, haces un commit para transferir esos cambios al repositorio local. El repositorio local mantiene un registro de todas las versiones de tu proyecto desde que comenzaste a usar Git. Es como un historial de todo tu trabajo. Aquí puedes volver a versiones anteriores, ver cambios antiguos, fusionar ramas, entre otras muchas cosas.

En resumen, el flujo de trabajo básico en Git es: realizas cambios en tu workspace, seleccionas cuáles de esos cambios quieres incluir en tu próximo commit añadiéndolos a la staging area, y luego confirmas esos cambios al repositorio local con un commit. 

Aquí puedes revisar en tan sólo 15 minutos las tareas más importantes que solemos realizar con Git en un proyecto de desarrollo de software.

Para practicar puedes crear tu propio proyecto e ir probando comandos al tiempo que observas sus efectos.

Otra opción bastante más divertida es completar, al menos, las 4 primeras fases de este juego.

2.5. Trabajo en equipo y mejora continua

El trabajo en equipo implica la colaboración de dos o más individuos organizados de tal manera que puedan cooperar en un proyecto común, el cual sería extremadamente difícil o imposible de lograr individualmente. Este enfoque se adopta también para optimizar y agilizar procesos que pueden estar obstaculizando el desarrollo de tareas cotidianas y el logro de objetivos en una organización.

En un entorno de trabajo en equipo, se combinan y maximizan las habilidades de los miembros, lo que resulta en una reducción del tiempo necesario para las tareas y un aumento en la eficiencia de los resultados obtenidos.

Sin embargo, no cualquier grupo de personas constituye un equipo de trabajo efectivo. Es importante alcanzar un nivel significativo de cohesión entre los miembros. Esto se logra fomentando la atracción interpersonal, estableciendo normas de conducta claras, contando con una figura de liderazgo eficaz, promoviendo una comunicación efectiva entre todos los integrantes, trabajando hacia objetivos comunes y estableciendo relaciones positivas.

La cohesión de un equipo se manifiesta en el compañerismo y el sentido de pertenencia que sienten sus miembros. Cuanto mayor sea la cohesión, mejor trabajarán los miembros del equipo y más productivos serán los resultados.

Cuando surgen dificultades en un equipo de trabajo, a menudo se forma un equipo especializado en mejora continua. Este equipo, compuesto por individuos que pueden ser del mismo o de diferentes departamentos, tiene la misión de mejorar la calidad y la productividad del equipo principal. Una vez resueltos los problemas, este equipo especializado puede disolverse.

Para la sincronización efectiva de tareas, especialmente en situaciones donde varios miembros trabajan en la misma parte de un proyecto, es fundamental implementar un control de versiones. Esto se logra mediante el uso de sistemas de control de versiones, cuya importancia y eficacia ya conocemos del apartado anterior.

En el desarrollo de software, el aumento de la complejidad implica un incremento en el número de líneas de código y, por ende, en las horas de desarrollo requeridas. Aunque pueda parecer que dos programadores realizarían el trabajo en la mitad del tiempo que uno, la realidad es que el trabajo en equipo potencia los esfuerzos de manera que se reduce aún más el tiempo de desarrollo y se incrementa la eficacia de los resultados.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *