Análisis y Diseño
Análisis y Diseño
Análisis y Diseño
Análisis y Diseño
Grupo 7
Integrantes:
Ica – Perú
2022
1
INDICE
INDICE................................................................................................................................................2
INTRODUCCION................................................................................................................................4
CONTENIDO.......................................................................................................................................4
10.1. Patrones......................................................................................................................24
2
10.2. Técnicas según Ble.....................................................................................................25
12.2. Consistencia................................................................................................................28
CONCLUSION..................................................................................................................................33
BIBLIOGRAFÍA................................................................................................................................34
3
INTRODUCCION
En el presente trabajo, exploraremos los fundamentos y las mejores prácticas del análisis y diseño
de sistemas de software. El análisis y diseño desempeñan un papel crucial en el desarrollo de
software, ya que establecen las bases para la construcción de sistemas robustos, eficientes y de alta
calidad. A través de esta investigación, examinaremos diversos aspectos, desde el proceso de
análisis y diseño hasta la importancia del encapsulamiento y las buenas prácticas de diseño.
Además, exploraremos principios clave, técnicas y herramientas que pueden ayudarnos a desarrollar
soluciones de software que cumplan con los requisitos del usuario y sean fáciles de mantener y
mejorar en el tiempo. A lo largo de este trabajo, descubriremos la importancia de un análisis
detallado para comprender las necesidades de los usuarios y cómo un diseño sólido puede influir en
la calidad y la eficiencia del software. Asimismo, reflexionaremos sobre la relevancia del
encapsulamiento y las buenas prácticas de diseño en la creación de sistemas mantenibles y flexibles.
A través de esta exploración, esperamos obtener una comprensión más profunda del análisis y
diseño de sistemas de software y cómo aplicar estas disciplinas en la práctica para lograr resultados
exitosos en el desarrollo de software.
CONTENIDO
El análisis y diseño de software es un proceso que implica comprender, definir y representar los
requisitos de un sistema de software, así como diseñar una solución estructurada y eficiente para
satisfacer esos requisitos. Estas etapas son fundamentales en el ciclo de vida del desarrollo de
software y son clave para construir sistemas de calidad que cumplan con las necesidades de los
usuarios y las organizaciones.
4
El análisis de software se centra en comprender y especificar los requisitos del sistema. Esto implica
identificar las necesidades de los usuarios, las funcionalidades requeridas, las restricciones y los
objetivos del sistema. Durante el análisis, se utilizan técnicas como entrevistas con los usuarios,
revisión de documentos, observación y modelado de procesos para recopilar y documentar los
requisitos de manera precisa.
Una vez que los requisitos se han recopilado y comprendido, se pasa al diseño de software. En esta
etapa, se define la arquitectura y la estructura del sistema, así como los componentes y las
interacciones entre ellos. El diseño del software se basa en principios y patrones de diseño, y busca
lograr un sistema modular, escalable, eficiente y mantenible. Se crean diagramas de diseño, como
diagramas de clases, diagramas de secuencia y diagramas de componentes, para visualizar y
comunicar la estructura del sistema.
El análisis y diseño de software ayuda a establecer una base sólida para el desarrollo y la
implementación del software. Al comprender los requisitos y diseñar una solución adecuada, se
reducen los riesgos de errores y cambios costosos en etapas posteriores del desarrollo. Además, un
análisis y diseño bien realizado permite una comunicación clara entre los desarrolladores, los
usuarios y los equipos involucrados en el proyecto, lo que mejora la colaboración y la calidad del
software final.
Es importante destacar que el análisis y diseño de software son actividades iterativas y evolutivas. A
medida que se obtiene más información y se realizan cambios, es posible volver a analizar y
rediseñar para mejorar continuamente el sistema en desarrollo.
El proceso de análisis y diseño de sistemas es una metodología que se utiliza para comprender,
planificar y crear soluciones efectivas en el desarrollo de sistemas de información. Este proceso
implica una serie de pasos o etapas que se siguen para analizar los requisitos, diseñar la solución y
preparar la implementación del sistema.
Identificación de necesidades:
En esta etapa inicial, se recopila información sobre las necesidades y problemas existentes en la
organización o en el proceso que se desea mejorar mediante el sistema de información. Se realizan
entrevistas con los usuarios y las partes interesadas para comprender sus requerimientos y
expectativas.
5
Recopilación de requisitos:
En esta etapa, se identifican, documentan y validan los requisitos del sistema. Se utiliza una
variedad de técnicas, como entrevistas, cuestionarios, observación de procesos y análisis de
documentos, para recopilar información detallada sobre las funcionalidades, reglas de negocio y
restricciones del sistema.
Análisis de requisitos:
En esta etapa, se analizan los requisitos recopilados para comprender su significado, relaciones y
prioridades. Se realizan actividades como la identificación de casos de uso, la creación de
diagramas de flujo y la elaboración de modelos de procesos para visualizar y comprender los flujos
de trabajo y las interacciones del sistema.
Diseño conceptual:
En esta etapa, se crea un diseño conceptual del sistema que proporciona una visión general de la
solución propuesta. Se definen los componentes principales del sistema, sus interacciones y las
tecnologías que se utilizarán. Se pueden emplear diagramas de casos de uso, diagramas de clases y
otros modelos para representar el diseño conceptual.
Diseño detallado:
En esta etapa, se elabora un diseño detallado del sistema, definiendo los aspectos técnicos y
funcionales en mayor detalle. Se desarrollan diagramas de secuencia, diagramas de actividad y otros
modelos que describen en profundidad el comportamiento y la estructura del sistema. También se
toman decisiones sobre la arquitectura, los lenguajes de programación, las bases de datos y otros
componentes técnicos.
Implementación:
En esta etapa, se lleva a cabo la construcción del sistema de acuerdo con el diseño detallado. Los
desarrolladores codifican el software, crean la base de datos y realizan todas las actividades
necesarias para implementar el sistema.
6
Pruebas y validación:
En esta etapa, se realizan pruebas exhaustivas para verificar que el sistema cumple con los
requisitos definidos. Se llevan a cabo pruebas unitarias, pruebas de integración y pruebas de
aceptación para identificar y corregir errores y asegurar que el sistema funcione correctamente.
Despliegue e implementación:
Entrevistas:
Las entrevistas son uno de los métodos más utilizados para recopilar información de los usuarios y
las partes interesadas. Se llevan a cabo sesiones de entrevistas uno a uno, donde se realiza una serie
de preguntas estructuradas o semiestructuradas para obtener información detallada sobre los
requisitos del sistema.
Cuestionarios:
Los cuestionarios son formularios con preguntas estandarizadas que se distribuyen a los usuarios y
las partes interesadas para recopilar información de manera sistemática. Los cuestionarios pueden
utilizarse para recopilar información cuantitativa y cualitativa sobre los requisitos del sistema.
Observación:
La observación directa de los procesos existentes y las interacciones de los usuarios puede
proporcionar una comprensión profunda de los requisitos del sistema. Al observar cómo se realizan
las tareas y cómo interactúan los usuarios con los sistemas actuales, se pueden identificar áreas de
mejora y necesidades no expresadas.
7
Las sesiones de lluvia de ideas son reuniones en las que se invita a los usuarios y las partes
interesadas a generar ideas y sugerencias relacionadas con los requisitos del sistema. Esta técnica
fomenta la creatividad y la participación activa de los participantes.
Prototipado:
La creación de prototipos o modelos rápidos del sistema puede ayudar a recopilar requisitos y
validar funcionalidades antes de la implementación final. Los prototipos permiten a los usuarios
experimentar y proporcionar retroalimentación sobre las características y el diseño propuestos.
El análisis de documentos existentes, como manuales, informes, formularios y otros registros, puede
proporcionar información valiosa sobre los procesos y los requisitos del sistema. Este análisis ayuda
a comprender las reglas de negocio, los flujos de trabajo y los requisitos legales o normativos.
Juego de roles:
Esta técnica implica la simulación de situaciones o escenarios en los que los participantes asumen
roles y actúan como usuarios del sistema. Esto ayuda a identificar necesidades y requisitos a través
de la interacción y el análisis de las acciones realizadas durante el juego de roles.
Entrevistas grupales:
Las entrevistas grupales permiten reunir a varias personas relevantes para el proyecto en una misma
sesión. Esto fomenta la colaboración y la discusión entre los participantes, lo que puede llevar a una
identificación más completa de los requisitos y perspectivas diversas.
Modelado de datos:
El modelado de datos es el proceso de representar la estructura lógica de los datos que serán
utilizados por el sistema. En esta etapa, se utilizan técnicas y notaciones específicas para crear
modelos conceptuales y diagramas que describen las entidades (objetos), atributos (propiedades) y
las relaciones entre ellos. Los modelos de datos ayudan a comprender la estructura y las
interacciones de los datos dentro del sistema.
8
El diseño de bases de datos es el proceso de convertir el modelo conceptual en una implementación
física utilizando un sistema de gestión de bases de datos (SGBD). En esta etapa, se definen las
tablas, columnas, restricciones y relaciones de la base de datos de acuerdo con el modelo
conceptual. También se consideran aspectos de rendimiento, seguridad y eficiencia en el diseño
físico de la base de datos.
El diseño de bases de datos implica tomar decisiones sobre la normalización de los datos para evitar
redundancias y garantizar la integridad de los mismos. Además, se deben considerar los tipos de
datos adecuados para cada atributo, las claves primarias y foráneas para establecer relaciones entre
las tablas, y la indexación para mejorar el rendimiento de las consultas.
El modelado de datos y el diseño de bases de datos son esenciales para garantizar una gestión
eficiente y coherente de la información en un sistema de software. Un buen diseño de base de datos
ayuda a asegurar la integridad y la calidad de los datos, facilita las consultas y operaciones de
actualización, y permite una escalabilidad y mantenimiento adecuados del sistema en el tiempo.
Consiste en diseñar visualmente las interfaces gráficas y definir la forma en que los usuarios
navegan, ingresan información y realizan acciones en el sistema.
Diseño visual:
Diseño de navegación:
Consiste en definir la estructura y la organización de la interfaz, incluyendo los menús, las barras de
navegación, los enlaces y los botones. El diseño de navegación debe ser intuitivo y permitir a los
usuarios moverse fácilmente por el sistema, acceder a las diferentes secciones y realizar las
acciones deseadas.
Diseño de interacción:
9
Se refiere a cómo los elementos de la interfaz responden a las acciones del usuario. Esto incluye
animaciones, transiciones, retroalimentación visual y sonora, entre otros aspectos. El diseño de
interacción busca guiar al usuario, proporcionar retroalimentación clara y mantener una interacción
fluida y natural.
Se trata de cómo se presentan y se estructuran los datos y la información en la interfaz. Esto implica
organizar la información de manera lógica y comprensible, utilizar jerarquías visuales y
proporcionar etiquetas claras y descriptivas. La organización de la información ayuda a los usuarios
a encontrar y comprender la información de manera eficiente.
Accesibilidad:
El diseño de interfaces de usuario también debe tener en cuenta la accesibilidad para garantizar que
todas las personas, incluidas aquellas con discapacidades o limitaciones, puedan utilizar el sistema
de manera efectiva. Esto implica considerar aspectos como el contraste de colores, el tamaño de
fuente, la compatibilidad con lectores de pantalla y otras prácticas de accesibilidad.
El diseño estructurado y orientado a objetos son dos enfoques diferentes utilizados en el diseño de
software.
Diseño estructurado:
10
El diseño orientado a objetos se basa en el concepto de objetos, que son entidades que combinan
datos (atributos) y comportamiento (métodos) relacionados. En este enfoque, el sistema se modela
como una colección de objetos que interactúan entre sí. El diseño orientado a objetos se centra en la
identificación de las clases y objetos relevantes para el sistema, sus relaciones y la definición de sus
atributos y métodos. Se utiliza el encapsulamiento, la herencia y el polimorfismo para mejorar la
reutilización del código, la modularidad y la flexibilidad del sistema.
Tanto el diseño estructurado como el orientado a objetos son enfoques válidos y ampliamente
utilizados en el desarrollo de software. El diseño estructurado es más adecuado para sistemas más
pequeños y menos complejos, donde la estructura y la lógica de control son fundamentales. El
diseño orientado a objetos es más adecuado para sistemas más grandes y complejos, donde la
reutilización, la modularidad y la extensibilidad son fundamentales. [1]
Durante esta etapa, el código fuente se traduce en un producto final, se configuran los servidores y
se instala el software en los entornos de producción o de prueba. La implementación implica la
ejecución de diversas actividades, como la compilación, la configuración, la instalación, la
migración de datos y la integración con otros sistemas, según sea necesario. Es importante seguir
buenas prácticas de desarrollo y asegurarse de que la implementación se realice de manera correcta
y eficiente.
Las pruebas de sistemas se realizan para verificar que el software cumpla con los requisitos
definidos y funcione correctamente. Algunos ejemplos de pruebas incluyen.
Pruebas unitarias:
Pruebas de integración:
11
Pruebas de aceptación:
Las pruebas de aceptación se realizan para verificar que el sistema cumpla con los requisitos
establecidos por los usuarios y las partes interesadas. Estas pruebas se enfocan en validar que el
sistema realice las funciones y entregue los resultados esperados de acuerdo con los criterios de
aceptación definidos.
Pruebas funcionales:
Las pruebas funcionales se centran en verificar que el sistema cumpla con las funcionalidades y
comportamientos especificados en los requisitos. Estas pruebas se realizan utilizando casos de
prueba que cubren los diferentes escenarios y casos de uso del sistema.
Pruebas de rendimiento:
Las pruebas de rendimiento se llevan a cabo para evaluar el rendimiento y la capacidad del sistema
bajo diferentes cargas y condiciones. Estas pruebas pueden incluir pruebas de carga, pruebas de
estrés y pruebas de rendimiento para medir la capacidad de respuesta, la velocidad y la estabilidad
del sistema.
Pruebas de seguridad:
Las pruebas de seguridad se realizan para identificar y evaluar posibles vulnerabilidades o brechas
de seguridad en el sistema. Estas pruebas se centran en probar la resistencia del sistema ante
posibles ataques, la protección de datos sensibles y el cumplimiento de los estándares de seguridad
establecidos.
Pruebas de usabilidad:
Las pruebas de usabilidad se centran en evaluar la facilidad de uso y la experiencia del usuario en el
sistema. Estas pruebas implican la participación de usuarios reales que interactúan con el sistema
para identificar posibles problemas de usabilidad y mejorar la interfaz de usuario.
El objetivo principal de las pruebas de sistemas es identificar y corregir los errores antes de que el
sistema se implemente completamente. También ayudan a garantizar la calidad y confiabilidad del
software.
Es importante destacar que la implementación y las pruebas de sistemas son procesos iterativos y se
llevan a cabo en varias etapas del ciclo de vida del desarrollo de software. A medida que se
implementan nuevas funcionalidades o se realizan cambios en el sistema, es necesario repetir el
12
proceso de implementación y pruebas para asegurarse de que todo funcione correctamente. Además,
las pruebas deben ser planificadas y ejecutadas de manera adecuada, utilizando estrategias y
herramientas apropiadas para cada tipo de prueba.
Mantenimiento correctivo:
Mantenimiento adaptativo:
Implica realizar cambios en el sistema para adaptarlo a nuevos requisitos o cambios en el entorno
tecnológico o empresarial. Esto puede incluir la modificación de funcionalidades existentes, la
incorporación de nuevas características o la integración con otros sistemas.
Mantenimiento preventivo:
Consiste en realizar actividades para prevenir problemas o mejorar el rendimiento del sistema. Esto
puede incluir la optimización de la base de datos, la actualización de componentes de software, la
aplicación de parches de seguridad y la realización de copias de seguridad regulares.
Mejora continua:
Se trata de buscar constantemente formas de mejorar el sistema y su rendimiento. Esto puede incluir
la identificación de áreas de mejora, la recolección de comentarios de los usuarios, la
implementación de nuevas funcionalidades, la optimización de procesos y la adopción de nuevas
tecnologías.
13
8. Estructura Interna del Software
Se refiere a cómo está organizado y se compone el código fuente y los componentes internos de un
sistema de software. Describe la forma en que los diferentes módulos, clases, funciones y
componentes se relacionan y trabajan juntos para lograr la funcionalidad del software.
La estructura interna del software es invisible para los usuarios finales y se enfoca en los detalles
técnicos de cómo se implementa el software. Incluye aspectos como la organización del código
fuente, la arquitectura del sistema, las relaciones entre los diferentes módulos y componentes, y la
forma en que se gestionan los datos y la lógica del programa.
Una estructura organizada del código fuente facilita la identificación y el uso de componentes
reutilizables. Los módulos o bloques de código bien definidos y separados permiten su fácil
extracción y uso en otras partes del sistema o en proyectos futuros, lo que mejora la eficiencia del
desarrollo y reduce la duplicación de código.
Simplifica la colaboración:
Una organización clara y consistente del código fuente facilita la colaboración entre varios
desarrolladores que trabajan en el mismo proyecto. Al tener una estructura común y acordada, los
miembros del equipo pueden entender y trabajar en diferentes partes del sistema de manera más
eficiente, evitando conflictos y facilitando la integración del código.
14
Mejora el mantenimiento y la escalabilidad:
Una organización adecuada del código fuente facilita el mantenimiento del software a lo largo del
tiempo. Los cambios y las actualizaciones se pueden realizar de manera más controlada y
sistemática, y es más fácil identificar y solucionar problemas o errores. Además, una estructura bien
organizada facilita la escalabilidad del software, ya que permite la adición o modificación de
funcionalidades sin afectar negativamente al resto del sistema.
La arquitectura del sistema se refiere a la estructura o diseño general de un sistema de software, que
describe los componentes principales, sus interacciones y la organización general del sistema. [2]
Componentes:
La arquitectura del sistema identifica los componentes principales que conforman el sistema de
software. Estos componentes pueden ser módulos, subsistemas o servicios individuales que
desempeñan una función específica dentro del sistema.
Interacciones:
Describe cómo los diferentes componentes del sistema interactúan entre sí. Esto incluye las
interfaces y los protocolos de comunicación utilizados para permitir la interacción y el intercambio
de datos entre los componentes.
Distribución y despliegue:
La arquitectura del sistema también aborda cómo se distribuyen físicamente los componentes y
cómo se despliega el sistema en el entorno de producción. Esto puede incluir consideraciones sobre
la escalabilidad, la redundancia y la disponibilidad del sistema.
Patrones arquitectónicos:
Los patrones arquitectónicos son enfoques comunes y probados para abordar problemas recurrentes
de diseño en la arquitectura del sistema. Algunos ejemplos de patrones arquitectónicos incluyen la
arquitectura en capas, la arquitectura orientada a servicios (SOA), la arquitectura de microservicios,
entre otros.
15
La arquitectura del sistema también considera los atributos de calidad que el sistema debe cumplir,
como la seguridad, el rendimiento, la escalabilidad, la usabilidad, la modularidad y la
mantenibilidad. La arquitectura del sistema debe estar diseñada para satisfacer estos atributos y
garantizar que el sistema cumpla con los requisitos y expectativas del cliente
Es importante destacar que la arquitectura del sistema puede variar según el tipo de sistema, los
requisitos del proyecto y las tecnologías utilizadas. Cada sistema tendrá su propia arquitectura única
que se adapta a sus necesidades y objetivos específicos.
Relación de dependencia:
Relación de llamada:
Ocurre cuando un componente invoca o llama a otro componente para ejecutar una función
específica. Esta relación se establece mediante la invocación de métodos o funciones de otro
componente. La relación de llamada puede ser directa, donde un componente llama directamente a
otro, o puede ser indirecta a través de una cadena de llamadas entre varios componentes.
Relación de asociación:
Representa una conexión lógica entre dos componentes que interactúan entre sí. A diferencia de la
relación de dependencia, la asociación implica una interacción más estrecha y continua entre los
componentes. Pueden intercambiar información, colaborar en la ejecución de tareas o tener una
relación más cercana en términos de funcionalidad.
Relación de herencia:
Es una relación que se establece entre una clase base y una clase derivada en la programación
orientada a objetos. La clase derivada hereda los atributos y métodos de la clase base, lo que
permite la reutilización de código y la creación de una jerarquía de clases.
16
Relación de composición:
Relación de agregación:
La gestión de datos implica el diseño y la implementación de estructuras de datos, así como las
operaciones necesarias para almacenar, acceder, modificar y eliminar los datos de manera eficiente
y confiable.
Modelado de datos:
Es el proceso de diseñar la estructura y las relaciones de los datos que se utilizarán en el sistema.
Esto implica la identificación de las entidades, atributos y relaciones relevantes, y la representación
de estos elementos utilizando técnicas como los diagramas de entidad-relación o los modelos de
datos.
Bases de datos:
Las bases de datos son sistemas de gestión de datos que permiten almacenar y recuperar grandes
volúmenes de información de manera estructurada. En la estructura interna del software, se utilizan
técnicas para interactuar con las bases de datos, como la definición de esquemas, la creación de
tablas y la ejecución de consultas para recuperar, insertar, actualizar y eliminar datos.
Acceso a datos:
Es el mecanismo a través del cual el software interactúa con la base de datos para leer y escribir
datos. Esto incluye el uso de lenguajes de consulta (como SQL) o interfaces de programación (como
17
las API de acceso a bases de datos) para realizar operaciones de lectura y escritura en la base de
datos.
Gestión de transacciones:
Optimización de consultas:
En sistemas que manejan grandes volúmenes de datos, es importante optimizar las consultas para
mejorar el rendimiento y la eficiencia de las operaciones de acceso a datos. Esto implica diseñar
índices adecuados, optimizar consultas y utilizar técnicas de caché para minimizar los tiempos de
respuesta y maximizar el rendimiento.
La lógica y el flujo del programa se refieren a la forma en que se estructuran y organizan las
instrucciones y las decisiones dentro de un programa de software. Esto incluye la secuencia de
acciones que se deben realizar y las condiciones que se deben cumplir para que el programa
funcione correctamente.
La lógica del programa se refiere a las reglas y las instrucciones que determinan cómo se procesan
los datos y se realizan las operaciones. Esto implica definir la secuencia de pasos que el programa
debe seguir para alcanzar un resultado deseado. La lógica del programa se establece utilizando
estructuras de control, como bucles, condicionales y funciones, que permiten la toma de decisiones
y la repetición de tareas.
18
Un buen diseño de la lógica y el flujo del programa es fundamental para que el software funcione
correctamente y cumpla con los requisitos establecidos. Una lógica clara y bien estructurada
asegura que las operaciones se realicen de manera correcta y eficiente, evitando errores y problemas
de funcionamiento. Además, un flujo de programa bien definido facilita la comprensión del código,
el mantenimiento y la depuración.
Organización y estructura:
Dividir el programa en funciones o módulos más pequeños y bien definidos para facilitar la
comprensión y el mantenimiento del código.
Estructuras de control:
Utilizar estructuras de control adecuadas, como condicionales (if-else), bucles (for, while) y
funciones, para controlar el flujo del programa y tomar decisiones basadas en ciertas condiciones.
Gestión de errores:
Comentarios y documentación:
En el ámbito del diseño de software, existen principios fundamentales que guían a los profesionales
en la creación de sistemas eficientes y de alta calidad. Estos principios actúan como pilares sobre
los cuales se sustenta un diseño sólido, permitiendo que los sistemas sean mantenibles, extensibles y
adaptables a medida que evolucionan los requisitos y las tecnologías.
Exploraremos en detalle algunos de los principios del diseño de software. Estos principios, fruto de
años de experiencia y mejores prácticas en la industria, se han establecido como guías confiables
para el desarrollo de soluciones de software robustas y sostenibles.
19
El libro "Clean Code: A Handbook of Agile Software Craftsmanship" de Robert C. Martin,
ampliamente reconocido en la comunidad de desarrollo de software, proporciona una valiosa
perspectiva sobre los principios de diseño y su importancia en la creación de software de calidad.
Según Martin, los principios de diseño son fundamentales para garantizar que nuestro código sea
legible, mantenible y escalable. En este libro, se abordan principios clave como la responsabilidad
única, el principio de abierto/cerrado, la sustitución de Liskov y muchos otros. A través de ejemplos
prácticos y casos reales, Martin ilustra cómo aplicar estos principios en el diseño de software para
lograr un código limpio y modular. Este enfoque basado en principios no solo mejora la calidad del
software, sino que también facilita su mantenimiento y extensión a medida que evolucionan los
requisitos. Como señala Martin, comprender y aplicar estos principios de diseño es fundamental
para convertirse en un artesano del software y construir sistemas de software sólidos y sostenibles.
[3]
Según Robert C. Martin, el principio de responsabilidad única establece que cada clase o módulo de
software debe tener una única responsabilidad o motivo para cambiar. Según Martin, esta es una de
las características fundamentales de un diseño de software limpio y efectivo. Al asignar una única
responsabilidad a cada componente, se mejora la modularidad, la legibilidad y la reutilización del
código. [3]
Martin ofrece ejemplos prácticos que ilustran cómo identificar y separar responsabilidades en el
diseño de software. También destaca la importancia de evitar la violación de este principio, ya que
la mezcla de múltiples responsabilidades en un solo componente puede llevar a un código difícil de
entender, mantener y probar.
Es importante tener en cuenta que la responsabilidad única no implica que una clase o módulo deba
ser extremadamente pequeño o contener solo unas pocas líneas de código. Más bien, se refiere a que
el componente debe tener una única razón para cambiar, es decir, una única área temática o una
única tarea específica que realiza.
20
9.2. OCP (Open/Closed Principle)
El principio de abierto/cerrado establece que las entidades de software, como clases o módulos,
deben estar abiertas para la extensión pero cerradas para la modificación. En otras palabras, se
busca diseñar componentes que sean flexibles y permitan agregar nuevas funcionalidades sin tener
que modificar el código existente.
Este principio es fundamental para lograr un diseño de software que sea fácilmente adaptable a los
cambios y evite introducir errores o efectos secundarios no deseados al realizar modificaciones. Al
seguir este principio, se promueve una arquitectura modular y escalable, ya que se pueden agregar
nuevas funcionalidades a través de extensiones o adición de nuevos componentes sin alterar el
código ya existente.
En su libro, Martin explora diferentes técnicas y patrones de diseño que permiten seguir este
principio. Uno de los enfoques recomendados es el uso de interfaces y la programación orientada a
objetos. Al definir interfaces claras y estables, se pueden agregar nuevas implementaciones que
cumplan con esa interfaz sin afectar el código existente. Esto permite que el software sea más fácil
de mantener, probar y evolucionar con el tiempo. [3]
Según Martin, el tercer principio del diseño de software es el principio de "Sustitución de Liskov",
también conocido como LSP (Liskov Substitution Principle).
El principio de sustitución de Liskov establece que los objetos de una clase base deben poder ser
reemplazados por objetos de sus clases derivadas sin alterar la integridad del programa. En otras
palabras, si una clase A es un subtipo de una clase B, entonces los objetos de tipo B deben poder ser
reemplazados por objetos de tipo A sin causar efectos adversos o violar el comportamiento esperado
del programa. [3]
21
En su libro, Martin resalta la estrecha relación entre el principio de Sustitución de Liskov y el
concepto de herencia en el diseño de software. Según él, cumplir con este principio implica que las
clases derivadas deben mantener el mismo contrato de comportamiento que la clase base. Esto
garantiza que los objetos derivados puedan ser utilizados de manera intercambiable con los objetos
de la clase base, sin generar conflictos o errores. En otras palabras, el principio de Sustitución de
Liskov busca asegurar que las clases derivadas sean capaces de actuar como sustitutos válidos de la
clase base, manteniendo la consistencia en su comportamiento.
Al seguir este principio, se fomenta una jerarquía de clases sólida y consistente, lo que facilita el
mantenimiento y la evolución del software. Además, promueve el diseño de interfaces y
abstracciones bien definidas, lo que a su vez mejora la modularidad y la reutilización de código.
En el libro "Design Patterns", los autores Eric Gamma, Richard Helm, Ralph Johnson y John
Vlissides abordan el principio de Segregación de interfaz como parte de su discusión sobre patrones
de diseño y su relación con la reutilización de software. [4]
Según los autores, el principio de Segregación de interfaz se basa en la idea de que las interfaces de
un sistema deben ser cohesivas y específicas para cada cliente o contexto de uso. En lugar de tener
interfaces grandes y monolíticas que contengan todas las funcionalidades posibles, se busca dividir
las interfaces en conjuntos más pequeños y especializados que satisfagan las necesidades de cada
cliente o módulo.
La razón detrás de este principio es evitar que los clientes dependan de funcionalidades que no
utilizan. Al dividir las interfaces en unidades más pequeñas y cohesivas, se permite que los clientes
solo dependan de las funcionalidades que realmente necesitan. Esto evita la introducción de
dependencias innecesarias y reduce el acoplamiento entre los diferentes componentes del sistema.
El libro discute cómo aplicar este principio utilizando patrones de diseño como el patrón de fachada
y el patrón de adaptador. Estos patrones permiten proporcionar interfaces específicas y
simplificadas a los clientes, ocultando la complejidad y las dependencias internas del sistema.
22
9.5. Principio de Inversión de control
Seemann explica que la Inversión de Control se refiere a la transferencia del control de la creación y
gestión de dependencias a un contenedor o framework externo, en lugar de que los componentes de
alto nivel lo manejen directamente. [5]
Resalta que los beneficios de la Inversión de Control y la Inyección de Dependencia incluyen una
mayor flexibilidad, desacoplamiento y facilidad de pruebas unitarias. Mediante la Inyección de
Dependencia, los componentes dependen de abstracciones o interfaces en lugar de depender de
implementaciones concretas, lo que promueve la reutilización de código, la modularidad y la
extensibilidad.
En cuanto a la aplicación del principio, Seemann proporciona guías prácticas para implementar la
Inversión de Control a través de la técnica de Inyección de Dependencia. Explica cómo configurar
un contenedor IoC, como Unity o Autofac, para administrar la creación y resolución de
dependencias en una aplicación .NET. También muestra ejemplos específicos y técnicas para
diferentes escenarios y tipos de aplicaciones.
Al seguir el principio de DRY, se mejora la mantenibilidad del código, ya que cualquier cambio o
corrección solo necesita hacerse en un solo lugar. Además, se fomenta la consistencia y la claridad
en el sistema, ya que la lógica se encapsula y se reutiliza de manera coherente.
23
10. Modelado de Software
Evans destaca la importancia de utilizar un lenguaje ubicuo compartido entre los expertos del
dominio y los desarrolladores de software. Un lenguaje ubicuo es aquel que se utiliza para describir
y comprender el dominio del problema de manera clara y precisa. Al establecer un lenguaje común,
se facilita la comunicación y la colaboración entre todas las partes involucradas en el desarrollo del
software. [7]
El autor también enfatiza la importancia de identificar y modelar adecuadamente las entidades clave
del dominio. Las entidades son objetos o conceptos que tienen una identidad única y una vida
significativa dentro del dominio. Evans explica cómo identificar las entidades centrales del dominio
y cómo modelarlas en el software de manera coherente.
10.1. Patrones
Según Eric Evans, los patrones de Repositorio y Especificación son herramientas clave para el
modelado y el diseño de software basado en el dominio. [7]
El patrón Repositorio se utiliza para abstraer el acceso y la persistencia de las entidades del
dominio. Proporciona una interfaz común para interactuar con las entidades y oculta los detalles de
implementación de cómo se almacenan y recuperan los datos. El Repositorio actúa como una capa
de abstracción entre la lógica de dominio y la capa de persistencia, permitiendo que las entidades se
manejen de manera coherente en diferentes contextos y tecnologías de almacenamiento.
El patrón Especificación se utiliza para definir y encapsular criterios de consulta en el dominio. Una
especificación describe una condición que debe cumplir un objeto o conjunto de objetos dentro del
dominio. Proporciona una forma de construir consultas de manera modular y expresiva, evitando la
proliferación de lógica de consulta en diferentes partes del código. Al utilizar el patrón
Especificación, es posible componer y reutilizar criterios de consulta de manera flexible, facilitando
la construcción de consultas complejas.
Estos patrones se complementan entre sí y se utilizan de manera conjunta para mejorar el diseño del
software basado en el dominio. El patrón Repositorio ayuda a abstraer y separar el acceso a los
datos, mientras que el patrón Especificación permite definir criterios de consulta de manera modular
y expresiva. Ambos patrones contribuyen a un diseño más limpio, desacoplado y mantenible del
software.
24
10.2. Técnicas según Ble
Según el autor del libro, Carlos Blé, el enfoque de Diseño Ágil con TDD (Desarrollo Dirigido por
Pruebas) es una forma efectiva de crear software de calidad. El libro se basa en la experiencia del
autor en un proyecto real y presenta técnicas y prácticas para el diseño ágil utilizando TDD. [8]
Destaca la importancia de la colaboración entre los desarrolladores y los stakeholders del proyecto,
así como el papel clave de las pruebas automatizadas en el proceso de diseño ágil. El autor muestra
cómo el TDD puede ayudar a mantener un código limpio, bien estructurado y altamente mantenible.
Blé explica cómo el Diseño Ágil con TDD permite un enfoque iterativo e incremental para el
desarrollo de software. Se enfoca en escribir pruebas automatizadas antes de escribir el código de
producción, lo que ayuda a guiar el diseño del software y a garantizar la calidad a lo largo del
proceso de desarrollo.
También presenta varias técnicas de diseño que se pueden aplicar en el contexto del desarrollo ágil
utilizando TDD (Desarrollo Dirigido por Pruebas).
10.2.1. Refactorizacion
La refactorización es una técnica que consiste en mejorar la estructura y el diseño del código sin
cambiar su comportamiento externo. Permite eliminar la duplicación, simplificar la lógica, mejorar
la legibilidad y reducir la complejidad del código.
Blé explora los principios SOLID, que son un conjunto de principios de diseño de software que
promueven un diseño modular y desacoplado. Estos principios incluyen Responsabilidad Única
(SRP), Abierto/Cerrado (OCP), Sustitución de Liskov (LSP), Segregación de Interfaz (ISP) e
Inversión de Dependencia (DIP). El autor explica cada uno de estos principios y cómo se pueden
aplicar en el diseño de software ágil.
Esta técnica se basa en establecer contratos claros entre diferentes componentes del sistema. Los
contratos especifican las responsabilidades y las expectativas de comportamiento de cada
componente, lo que ayuda a garantizar la correcta interacción y colaboración entre ellos. Blé
muestra cómo utilizar esta técnica en el diseño de software ágil para mejorar la comunicación y la
claridad en el sistema.
25
10.2.4. Pruebas Unitarias
Las pruebas unitarias desempeñan un papel fundamental en el diseño ágil con TDD. Blé resalta la
importancia de escribir pruebas automatizadas antes de escribir el código de producción. Estas
pruebas actúan como una guía para el diseño del software y ayudan a garantizar la calidad del
código. El autor proporciona consejos y ejemplos para escribir pruebas efectivas y mantenibles.
En el libro, Norman explora los principios fundamentales del diseño centrado en el usuario y cómo
aplicarlos al diseño de interfaces. Aborda temas como la visibilidad, la retroalimentación, la
conceptualización y la affordance (características físicas que sugieren cómo utilizar un objeto). [9]
El autor utiliza ejemplos para entender mejor esto. Por ejemplo, en el caso de las puertas, Norman
analiza cómo un diseño deficiente puede llevar a la confusión y dificultad para los usuarios. Por
ejemplo, una puerta con una manija que se ve como si se debe tirar podría llevar a las personas a
empujarla incorrectamente. Norman destaca la importancia de un diseño claro y consistente,
utilizando señales visuales y affordances adecuadas, como placas que indiquen si se debe empujar o
jalar.
En cuanto a los interruptores de luz, Norman explora cómo un mal diseño puede resultar en una
interacción confusa o incómoda para los usuarios. Por ejemplo, interruptores que no tienen una
indicación clara de su estado (encendido o apagado) pueden hacer que las personas no estén seguras
de cómo operarlos. Norman sugiere que los interruptores de luz deben tener un diseño visualmente
distinguible y proporcionar retroalimentación perceptible, como un indicador luminoso, para que
los usuarios puedan comprender fácilmente su estado.
En "Clean Code", Martin destaca la importancia de las pruebas de software como parte integral del
proceso de desarrollo. Explica cómo el diseño de software puede influir en la facilidad de realizar
pruebas efectivas. El autor promueve la escritura de código que sea fácil de probar, aplicando
principios como la responsabilidad única y la inyección de dependencia para permitir pruebas
unitarias más simples y mantenibles. [3]
26
Discute también cómo un buen diseño puede facilitar las tareas de mantenimiento. Él enfatiza la
importancia de escribir un código limpio y modular, utilizando principios como la cohesión y el
bajo acoplamiento. Estos principios ayudan a reducir la complejidad, permitiendo que el software
sea más fácil de entender, modificar y extender en el futuro.
Son un conjunto de directrices y enfoques que se aplican durante el proceso de diseño de software
con el objetivo de crear un sistema bien estructurado, de alta calidad y fácilmente mantenible. Estas
prácticas no solo se centran en aspectos visuales o estéticos, sino también en la funcionalidad, el
rendimiento y la experiencia del usuario. A continuación, se detallan algunos aspectos clave de las
buenas prácticas de diseño: [10]
Para hacer más enriquecedor este punto de la simplicidad, a continuación, diré 4 maneras para
lograr esta simplicidad en nuestros diseños.
Mantener la claridad. – Según Euphemia W., entiende y diseña para los objetivos
principales de los usuarios. Ya sea que el diseño sea sobre un sitio web para un minorista o
un producto ya para una empresa más grande, el mantener la claridad en la interfaz de
usuario debe ser clave, se debe llamar la atención sobre los aspectos centrales de la página
en la que quieres que tus usuarios centre su atención. A continuación, pueden ver un
ejemplo de un popular registrador de dominios de internet y la empresa de alojamiento web,
en sitio web llamada GoDaddy del 2005 y luego vemos para la misma empresa, pero su
página en 2016, ya dando a resaltar la simplicidad y claridad del diseño. [11]
Hacer uso de la automatización. – Según Euphemia W., diseñar para una cantidad mínima
de esfuerzo consciente y cognitivo. Esto tiene que ver con la tendencia de los humanos por
realizar tareas comunes y practicas con una cantidad mínima de esfuerzo. Un ejemplo es la
tostadora, ya que esta requiere una cantidad mínima de conciencia consciente el poder
usarla gracias a la 'automaticidad", y se puede apreciar como una interfaz diseñada para la
27
automatización resiste al paso del tiempo. Pero si queremos un ejemplo más afín con
nuestro concepto de la tecnología las aplicaciones de mensajería como WhatsApp y
Messenger, muestra poca variación, gracias de nuevo al diseño alienado con automatizar el
proceso cognitivo del usuario al usar la aplicación.
Opciones Limite. – E el diseño para un fuerte 'aroma a información'. Se refiere al hecho de
querer ver las cosas relevantes para nuestro objetivo actual, esto se llamó "seguir el olor de
la información". Donde se sigue una ruta de interés donde la información esencial esta
centralizada o a la vista. La meta es limitar las opciones y diseñar para tener un fuerte
aroma de información puede ayudarlo a eliminar la carga que es la indecisión y vacilación
de los usuarios.
Reduzca el abismo de ejecución. – Haga que sus usuarios ven como su producto puede
ayudarlos a alcanzar sus objetivos. La meta acá es reducir el abismo de ejecución es decir el
tener tantas opciones y ejecutar sin para enlaces para lograr nuestro objetivo, mientas más
estrecho hagamos el abismo de ejecución, más probables es que el usuario entienda como
interactuar con tu interfaz. Hacer el producto lo suficientemente simple para que el usuario
lo vea como una herramienta eficiente para lograr sus objetivos.
12.2. Consistencia
Este punto se refiere a mantener una apariencia y comportamiento coherentes en todas las partes de
una aplicación o sistema. Es decir, mantener ya patrones predefinidos, utilizar elementos visuales y
de interacción de manera consistente, y garantizar acciones y comportamientos que sean predecibles
para los usuarios. [12]
Como ejemplo imaginemos que estamos diseñando unas aplicaciones de recetas de cocina. La
consistencia podría partirse en 2 partes:
Estilo Visual. - es decir los colores, Tipografía y elementos gráficos a usar. Todo tendría
colores cálidos y terrosos, fuentes legibles y elementos gráficos relacionados con la cocina.
Y lograr mantener este estilo en todas las pantallas, donde los usuarios sabrán fácilmente
que están interactuando con la misma aplicación.
Estructura de Navegación. - tener esta parte consistente significa, utilizar una disposición
lógica y predecible de los elementos de navegación en todas las pantallas. Ejemplo: tener
una barra de navegación en la parte inferior para mantener la consistencia en la estructura
de navegación en todo momento, y no cambiar cada rato que el usuario navegue.
28
Recordar: La consistencia se puede aplicar en muchos aspectos, como los botones, recetas,
instrucciones de la receta, etc. Pero el objetivo es que los usuarios están cómodos y familiarizados
con el software, y puedan interactuar y navegar con facilidad.
Como su nombre lo dice se enfoca en la reutilización ya componente existentes para evitar todo el
esfuerzo de crear otro de cero y mejorar así la eficiencia. Un pequeño ejemplo es lo que en el
mercado de desarrollo web se usa que es un framework como Django o Ruby on Rails que ya te
brindan funcionalidades predefinidas para reutilizar en multiples proyectos.
Un ejemplo práctico seria, imaginemos que estás desarrollando una aplicación de gestión de tareas.
Para aplicar la separación de preocupaciones, puedes dividir el sistema en los siguientes
componentes:
29
actualización y eliminación de tareas, así como otras acciones relacionadas con la gestión
de tareas.
Componente de Persistencia de Datos: Este componente se encarga de interactuar con una
base de datos o algún otro medio de almacenamiento para guardar y recuperar la
información de las tareas. Se preocupa de la persistencia y acceso a los datos, realizando
consultas y actualizaciones en la capa de almacenamiento.
Al separar las preocupaciones de esta manera, cada componente tiene una responsabilidad clara y
limitada. Por ejemplo, si en el futuro necesitas cambiar la base de datos que utilizas para almacenar
las tareas, solo tendrías que modificar el componente de Persistencia de Datos sin afectar la Interfaz
de Usuario ni la Lógica de Negocio. Esto facilita el mantenimiento y evolución del sistema, ya que
los cambios se pueden realizar en partes aisladas sin afectar a todo el sistema. Este ejemplo práctico
ilustra cómo la separación de preocupaciones puede ayudar a crear un diseño de software más
modular, mantenible y escalable. Al tener componentes independientes y cohesivos, se facilita el
desarrollo, las pruebas y el control de calidad, ya que cada componente se puede examinar y probar
por separado, permitiendo un enfoque más efectivo en cada área de responsabilidad.
Pruebas Practicas. – Las pruebas unitarias son pruebas automatizadas que se centran en
verificar el correcto funcionamiento de componentes individuales o unidades de código de
manera aislada. Se enfocan en probar cada unidad de código de forma independiente para
garantizar que cumpla con los requisitos y funcionalidades esperadas. Las pruebas unitarias
se suelen escribir en un entorno de desarrollo como xUnit y se ejecutan frecuentemente para
atrapar errores en etapas tempranas del desarrollo. [15]
Ejemplo práctico de prueba unitaria: Supongamos que tienes una función "sumar" en un módulo de
código que toma dos números como entrada y devuelve la suma de ellos. Para una prueba unitaria,
escribirías casos de prueba que cubran diferentes escenarios posibles, como sumar dos números
positivos, sumar un número positivo y un número negativo, o sumar cero con un número positivo.
Cada caso de prueba verificaría que la función "sumar" devuelve el resultado esperado para cada
combinación de números de entrada.
Pruebas de Integración. – Las pruebas de integración se realizan para verificar que los
diferentes componentes de un sistema funcionen correctamente juntos cuando se integran.
Estas pruebas evalúan la interacción y comunicación entre los componentes y aseguran que
las interfaces entre ellos estén correctamente implementadas. Las pruebas de integración
30
son fundamentales para detectar problemas de interoperabilidad y asegurar que los
diferentes componentes se comporten como se espera en conjunto.
31
Facilita el entendimiento: La documentación adecuada ayuda a los desarrolladores y
equipos de control de calidad a comprender rápidamente cómo funciona el software y cómo
realizar pruebas efectivas.
Aumenta la productividad: Una documentación completa y clara reduce el tiempo y los
esfuerzos necesarios para realizar tareas de desarrollo y pruebas, lo que aumenta la
productividad del equipo.
Mejora la calidad del software: La documentación adecuada permite una comprensión
precisa de las funcionalidades y requisitos, lo que ayuda a identificar y corregir problemas
más rápidamente durante el proceso de control de calidad.
Permite la colaboración: Una documentación bien estructurada y accesible facilita la
colaboración entre los desarrolladores, probadores y otros miembros del equipo, ya que
todos tienen acceso a la misma información relevante.
Facilita el mantenimiento y la escalabilidad: Una documentación actualizada y precisa
permite realizar cambios y actualizaciones de manera más sencilla, lo que facilita el
mantenimiento y la escalabilidad del software a largo plazo.
Podemos resumir este punto que, la documentación adecuada en el contexto del control de calidad y
las pruebas de software implica crear y mantener una documentación clara, completa y precisa que
brinde información relevante para los desarrolladores y equipos de control de calidad. Proporciona
beneficios significativos, como un mejor entendimiento, mayor productividad, mejora de la calidad
del software, facilitación de la colaboración y apoyo al mantenimiento y escalabilidad a largo plazo.
32
CONCLUSION
En este trabajo, se ha abordado una amplia gama de temas relacionados con el análisis y diseño de
sistemas de software. El análisis y diseño son etapas fundamentales en el proceso de desarrollo de
software, ya que sientan las bases para la construcción de sistemas robustos y de calidad.
El análisis de requisitos nos permite comprender a fondo las necesidades y expectativas de los
usuarios y stakeholders, lo que nos ayuda a definir de manera clara y precisa los objetivos y
funcionalidades del sistema. Por otro lado, el diseño nos permite traducir esos requisitos en una
arquitectura y estructura adecuadas del software.
Una de las consideraciones clave en el diseño es el encapsulamiento, que consiste en agrupar datos
y comportamientos relacionados en unidades coherentes y protegerlos del acceso no autorizado. El
encapsulamiento mejora la modularidad y la mantenibilidad del código, ya que nos permite
modificar internamente la implementación de una clase sin afectar a otras partes del sistema.
Además, el encapsulamiento favorece la reutilización del código y reduce el acoplamiento entre
componentes.
Es importante tener en cuenta buenas prácticas de diseño durante todo el proceso de desarrollo.
Estas prácticas incluyen la simplicidad, la claridad, la modularidad y la separación de
preocupaciones. Al aplicar estas prácticas, podemos lograr un código más legible, mantenible y
flexible.
La reflexión sobre la importancia del análisis y diseño nos lleva a comprender que estos pasos
iniciales son esenciales para evitar problemas futuros y garantizar el éxito del proyecto. Un análisis
y diseño adecuados nos permiten anticipar y abordar los desafíos técnicos y de negocio, así como
establecer una base sólida para la implementación y el mantenimiento del sistema.
33
BIBLIOGRAFÍA
[1] Kenneth E. Kendall; julie E. Kendall, Análisis y Diseño de Sistemas, Ciudad de Mexico -
Mexico: Pearson Educación, 2005.
[2] Gomez Fuentes Maria; Cervantes Ojeda, Jorge; Gonzalez Perez, Pedro, «Fundamentos de
ingenieria de software,» Universidad Autónoma Metropolitana, Cuajimalpa - Mexico, 2019.
[3] R. C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship. NJ: Prentice Hall
PTR, 2008.
[4] Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, Design Patterns: Elements of
Reusable Object-Oriented Software. Grady Booch, 1994.
[6] D. Thomas y A. Hunt, The Pragmatic Programmer: Your Journey to Mastery. 1999.
[7] E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-
Wesley, 2003.
[9] D. A. Norman, The Design of Everyday Things. New York: Basic Books, Inc., 2002.
[10] Autentia, "Software Design Principios y patrones del desarrollo de software", Autentia, Vol.1,
pp. 20, 2019.
[11] Euphemia W., "Simplicity in Design: 4 Ways to Achieve Simplicity in Your Designs",
Interaction Des. Found., pp. 8, 2021.
[13] E. Gamma, Design Patterns: Elements of Reusable Object - Oriented Software. Boston:
Addison-Wesley Professional, 2021.
[14] Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship. New York:
Pearson, 2008.
34
[15] "xUnit Test Patterns: Refactoring Test Code" de Gerard Meszaros. Boston: Addison-Wesley,
2007.
[16] Google. "Developer Documentation Style Guide". Google developer documentation style
guide. https://developers.google.com/style (accedido el 10 de julio de 2023).
35