El software tiene características particulares que lo diferencian de otros productos construidos por las personas. No se desgasta como una máquina, no puede verse completo de una sola mirada, puede modificarse muchas veces y suele representar reglas, procesos y decisiones de una organización.
Estas características explican por qué desarrollar software es difícil. Muchas veces los problemas no aparecen por falta de conocimiento de un lenguaje de programación, sino porque el sistema crece, cambia, se integra con otros sistemas y acumula decisiones que no son visibles para todos.
En este tema estudiaremos tres características centrales: complejidad, cambio e invisibilidad. Comprenderlas permite entender mejor la necesidad de aplicar Ingeniería de Software.
La complejidad del software no se debe solamente a que haya muchas líneas de código. También aparece por la cantidad de relaciones entre partes, reglas, datos, usuarios, permisos, interfaces, errores posibles, tecnologías e integraciones.
Un sistema puede tener miles de elementos que interactúan entre sí. Una modificación en una regla de negocio puede afectar una pantalla, una API, una base de datos, un reporte, una prueba automatizada y una integración externa.
La complejidad aumenta cuando el sistema debe responder a muchas situaciones distintas:
No toda la complejidad tiene el mismo origen. Podemos distinguir entre complejidad esencial y complejidad accidental.
| Tipo | Significado | Ejemplo |
|---|---|---|
| Complejidad esencial | Proviene del problema que el sistema debe resolver. | Un sistema de impuestos debe contemplar muchas reglas legales reales. |
| Complejidad accidental | Proviene de decisiones técnicas, herramientas, organización deficiente o código innecesariamente difícil. | Una regla simple está duplicada en diez archivos y cada copia funciona distinto. |
La Ingeniería de Software no puede eliminar la complejidad esencial sin cambiar el problema. Pero sí puede reducir la complejidad accidental mediante buen diseño, modularidad, pruebas, documentación y refactorización.
Cuando la complejidad no se administra, el proyecto empieza a mostrar síntomas claros:
Estas señales indican que el sistema necesita más orden interno, no solamente más esfuerzo.
Otra característica fundamental del software es su tendencia al cambio. A diferencia de muchos productos físicos, el software puede modificarse después de entregado, y esa posibilidad genera expectativas: los usuarios esperan mejoras, correcciones y adaptaciones.
Los cambios pueden aparecer por muchos motivos:
Por eso, un sistema debe pensarse para evolucionar. No se trata de anticipar todos los cambios posibles, sino de evitar diseños que hagan demasiado costoso cualquier cambio razonable.
Los cambios no siempre tienen la misma finalidad. Algunos corrigen problemas, otros adaptan el sistema y otros agregan valor.
| Tipo de cambio | Propósito | Ejemplo |
|---|---|---|
| Correctivo | Corregir defectos encontrados. | Arreglar un cálculo incorrecto en una factura. |
| Adaptativo | Ajustar el sistema a cambios del entorno. | Modificar una integración porque cambió una API externa. |
| Perfectivo | Mejorar funcionalidades, rendimiento o experiencia. | Agregar filtros avanzados a un reporte usado diariamente. |
| Preventivo | Reducir riesgos futuros y facilitar mantenimiento. | Refactorizar un módulo antes de agregar nuevas reglas. |
Modificar software puede ser barato o muy costoso según cómo esté construido. Si el sistema tiene responsabilidades separadas, pruebas y documentación útil, un cambio puede realizarse con confianza. Si el sistema está desordenado, cada cambio se vuelve riesgoso.
El costo del cambio depende de factores como:
Una meta importante de la Ingeniería de Software es mantener el costo del cambio dentro de límites razonables.
El software no puede observarse completo como se observa un edificio, una máquina o un plano físico. Podemos ver pantallas, diagramas, código, bases de datos o documentación, pero ninguna de esas representaciones muestra todo el sistema de una vez.
Esta invisibilidad hace difícil responder preguntas como:
Como no podemos ver el sistema completo de forma directa, necesitamos modelos, diagramas, documentación, pruebas, trazabilidad y herramientas de análisis.
Para trabajar con algo invisible, usamos representaciones. Cada una muestra una parte del sistema y oculta otras.
| Representación | Qué ayuda a ver | Límite |
|---|---|---|
| Código fuente | La implementación concreta. | Puede ser demasiado detallado para entender el sistema completo. |
| Diagramas | Estructura, comportamiento, relaciones o flujos. | Son simplificaciones y pueden quedar desactualizados. |
| Documentación | Decisiones, reglas, instrucciones y contexto. | Depende de que se mantenga útil y vigente. |
| Pruebas | Comportamientos esperados y casos importantes. | No muestran todos los escenarios posibles. |
| Logs y métricas | Comportamiento del sistema en ejecución. | No explican por sí solos todas las causas. |
Un programa no se gasta por ejecutarse muchas veces. Si el mismo código se ejecuta con las mismas condiciones, no debería fallar por desgaste físico. Sin embargo, el software puede deteriorarse de otra manera.
Ese deterioro ocurre cuando el entorno cambia o cuando se acumulan modificaciones sin suficiente cuidado. Por ejemplo:
Por eso, aunque el software no se desgaste físicamente, puede volverse más difícil de mantener y menos adecuado para su contexto.
Un sistema no vive aislado. Depende de hardware, sistema operativo, bases de datos, navegadores, redes, servicios externos, usuarios, reglas legales, procesos de negocio y otros sistemas.
Cuando el entorno cambia, el software puede necesitar adaptación. Por ejemplo, una aplicación que funcionaba correctamente puede presentar problemas si cambia la versión del navegador, si aumenta mucho la cantidad de usuarios o si una integración externa empieza a responder de otra manera.
Esta dependencia del entorno obliga a pensar en compatibilidad, monitoreo, actualización, pruebas en distintos ambientes y gestión de configuración.
Las características vistas tienen consecuencias directas en la forma de trabajar:
| Característica | Problema que genera | Prácticas que ayudan |
|---|---|---|
| Complejidad | Es difícil comprender todas las relaciones del sistema. | Modularidad, arquitectura, revisión de código y pruebas. |
| Cambio | Los requisitos y el entorno evolucionan constantemente. | Diseño mantenible, control de versiones, automatización y gestión de alcance. |
| Invisibilidad | No se puede ver el sistema completo de una sola mirada. | Diagramas, documentación, trazabilidad, métricas y modelos. |
| Dependencia del entorno | El sistema puede fallar aunque el código no haya cambiado. | Gestión de configuración, monitoreo y pruebas en ambientes representativos. |
| Deterioro por evolución | Los cambios acumulados pueden volver el sistema difícil de mantener. | Refactorización, gestión de deuda técnica y mejora continua. |
Imaginemos una tienda en línea. Al principio puede parecer simple: mostrar productos, agregar al carrito y pagar. Pero rápidamente aparecen muchas condiciones:
La complejidad surge por la combinación de reglas. El cambio aparece cuando se agregan promociones, medios de pago o nuevas políticas. La invisibilidad aparece porque ninguna pantalla muestra todas las relaciones internas del sistema.
Cuando no se reconocen estas propiedades del software, suelen cometerse errores como:
La Ingeniería de Software ayuda a reconocer estos riesgos antes de que se transformen en problemas difíciles de corregir.
El software es difícil de desarrollar no solo porque requiere programar, sino porque combina complejidad, cambio e invisibilidad. Estas características hacen que los sistemas puedan volverse difíciles de entender, modificar y mantener si no se trabajan con método.
Para quien comienza, la idea principal es esta: la Ingeniería de Software existe porque el software cambia, crece y no puede comprenderse completamente sin modelos, prácticas y acuerdos de trabajo.
En el próximo tema estudiaremos a los actores interesados: usuarios, clientes, equipo y organización, para comprender quiénes influyen en un proyecto de software y por qué sus necesidades pueden ser distintas.