INGENIERÍA DE SOFTWARE 2 2003-2004 Guiones de clase · Tema II – Requisitos del software...

33
1 INGENIERÍA DE SOFTWARE 2 2003-2004 Guiones de clase

Transcript of INGENIERÍA DE SOFTWARE 2 2003-2004 Guiones de clase · Tema II – Requisitos del software...

1

INGENIERÍA DE SOFTWARE 2 2003-2004

Guiones de clase

2

Presentación

Introducción � Unidad 1 – Introducción a la ingeniería de requisitos

Tema I – Requisitos del usuario (captura de requisitos)

� Unidad 2 – Estándares de documentación en el SPD (IEEE, ESA) � Unidad 3 – Requisitos del usuario: interacción con el cliente � Unidad 4 – Requisitos del usuario: obtención y descripción

Tema II – Requisitos del software (análisis de requisitos)

� Unidad 5 – Requisitos del software: tipos de requisitos � Unidad 6 – Requisitos del software: propiedades deseables � Unidad 7 – Requisitos del software: organización y calidad

Tema III – Diseño arquitectónico (diseño de alto nivel)

� Unidad 8 – Descomposición, marcos y patrones � Unidad 9 – Estilos arquitectónicos (1) � Unidad 10 – Estilos arquitectónicos (2)

Tema III – Diseño detallado (diseño de bajo nivel)

� Unidad 11 – Técnicas generales � Unidad 12 – Patrones de diseño (1) � Unidad 13 – Patrones de diseño (2)

3

1. Introducción a la ingeniería de requisitos

Fuentes � Braude, capítulo 3, pp. 136-141 (se citan páginas entre paréntesis para cada apartado)

Objetivos

� qué son los requisitos de usuario � necesidad y beneficios � cómo y de dónde se obtienen � importancia de la documentación escrita � cómo se genera el documento que los contiene

Introducción (p135)

� Obtener los requisitos correctos es un proceso difícil � Este proceso consiste en una interacción cuidadosa con los interesados (stakeholders)

en la aplicación � El documento de requisitos es uno de los productos (o artefactos) del proceso de

desarrollo de software (fig 7 en p6) Significado del análisis de requisitos (p136)

� Conceptualizar y expresar conceptos en una forma concreta � La mayor parte de los defectos en el software entregado tienen su origen en el análisis

de requisitos, y son en general los más difíciles de reparar � Para construir algo, antes hay que entender qué es ese “algo” � El proceso de entender y documentar se llama análisis de requisitos � En general, los requisitos expresan qué debe hacer una aplicación, sin decir cómo debe

hacerlo: expresan el punto de vista del cliente, que sabe lo que quiere, pero no tiene por qué saber cómo conseguirlo (en el mejor de los casos)

o A menudo el cliente ni siquiera sabe lo que quiere o Tarea del Analista es ayudar a que el cliente se exprese

� Ejemplo: o El sistema permitirá al usuario consultar el saldo de su cuenta (sí). o Los saldos de clientes se almacenarán en una tabla llamada Saldo en una base

de datos Access (no). � Los requisitos pueden estar estructurados en distintos niveles de detalle. � Excepciones: puede ocurrir que usar Access sea un requisito

o Existen distintos niveles de abstracción en los requisitos, debido a que suelen provenir de distintas fuentes (distintos interlocutores con distinto nivel de conocimientos tecnológicos)

o Ejemplo: el informático de la empresa nos habla de los sistemas con los que deberá interactuar el nuestro, mientras que el jefe de contabilidad nos proporciona una mejor visión sobre el conjunto de procesos del área

� El resultado del análisis de requisitos es un documento que recoge los requisitos del usuario y puede tener distintos nombres según el estándar de documentación seguido:

o IEEE: Especificación de Requisitos Software o ESA: Documento de Requisitos de Usuario

� Los requisitos de usuario tienen valor contractual y establecen los límites de la aplicación en cuanto a la funcionalidad que deben satisfacer

� Los requisitos de usuario pueden estar sujetos a normas de confidencialidad y propiedad intelectual

4

Requisitos-C y Requisitos-D (p137) � ¿De quién son los requisitos, del cliente o del desarrollador? Dos niveles � Primer nivel: Requisitos del Cliente (Customer Requirements)

o deseos y necesidades del cliente, expresados en lenguaje comprensible por él o audiencia primaria: cliente o audiencia secundaria: desarrollador

� Segundo nivel: Requisitos del Desarrollador (Developer / Detailed Requirements) o Forma estructurada y específica o audiencia primaria: desarrollador o audiencia secundaria: cliente

� Crítica: la distinción entre los dos niveles no es muy clara, sólo basada en la forma (no estructurada/estructurada). Forma, audiencia y contenido (¿contenido = nivel de detalle?). La finalidad última es la misma.

� Distintas nomenclaturas y clasificaciones, misma idea de fondo o Clásica/IEEE:

� Una única fase: Análisis de requisitos � Único documento Especificación de Requisitos con los requisitos C y D

o USDP/ESA: � Dos fases: Requisitos - Análisis � Dos documentos: Requisitos de Usuario, Requisitos del Software

� Colaboración y comunicación fluida entre clientes y desarrolladores para lograr el éxito en el producto: cuanto más completo y menos ambiguo sea el conjunto de Requisitos-C, más probabilidades de éxito

Por qué es necesario escribir los requisitos (p137)

� Es obvio incluso para el novato, pero con demasiada frecuencia se ignora o deja pasar � ¿No quedan bien expresados en el código fuente? No, no funciona:

o Sin requisitos el equipo no sabe cuál es su objetivo, no puede inspeccionar su trabajo, no puede probarlo, no puede analizar su productividad, no puede reflexionar sobre sus prácticas, no puede predecir el tamaño y esfuerzo del siguiente trabajo, no puede satisfacer a sus clientes. Brevemente, no hay ingeniería profesional sin requisitos escritos.

� Cada uno de los requisitos debe ser... (p138) o Expresado con propiedad o Fácilmente accesible para todo el personal involucrado o Numerado de forma unívoca o Acompañado por pruebas que lo verifiquen o Tenido en cuenta en el diseño y el código o Probado aisladamente y con otros requisitos o Validado por las pruebas al finalizar la construcción de la aplicación

� Sin requisitos escritos sería imposible hacer todo esto Plan de trabajo para obtener los requisitos (p139)

� Identificar al cliente (clientes posibles, seleccionar) � Entrevistar al cliente (antes, planificar) � Escribir los requisitos del cliente (sucesivas versions) � Revisar los requisitos con el cliente � Repetir los pasos hasta que el cliente firme el “conforme” del documento

5

Desafíos y ventajas de los requisitos (p140) � Un defecto en los requisitos es 20-50 veces más caro de reparar si se desliza sin

corregir en el resto del proceso de desarrollo de software (sin contar con el daño que sufre el prestigio del desarrollador)

� Si el beneficio es tan grande, ¿por qué tan a menudo se omite el análisis de requisitos? o Los clientes normalmente no tienen claro lo que quieren al principio, sólo una

idea vaga, y esto convierte el análisis de requisitos en una tarea más difícil o Solución: sucesivas iteraciones Requisitos-Diseño-Implementación

� Es una necesidad, no un lujo (voy despacio porque tengo prisa, no puedo permitirme el lujo de gastar tan poco)

� Sin requisitos, no es posible realizar pruebas (que sí se consideran esenciales) � Muchas organizaciones no logran escribir los requisitos: esto no significa que no los

usen, sino que sólo existen en las mentes de los ingenieros. Otro peligro: la rotación de personal. No es extraño que muchos proyectos nunca terminen.

� Un problema más sutil: escribir sólo la primera versión de los requisitos, pero sin mantenerlos al día en sucesivas iteraciones. Para poder actualizar el documento de requisitos es necesario que esté bien organizado.

� La adecuada comprensión de los requisitos es la base del acuerdo sobre la aplicación y de la relación contractual.

� Escribir es pensar. Escribir código prematuramente es como echar cemento sin saber cómo va a ser el puente ni dónde tiene que ir.

� El rechazo o desgana para escribirlos no es porque sea una tarea trivial e inútil, sino porque es demasiado difícil. La profesionalidad lo exige.

6

2. Estándares de documentación

Fuentes � ESA Software Engineering Standards (web de la asignatura) � Braude, cap. 1, p. 30; cap. 3, p. 140; cap. 4, pp. 187, 202

Objetivos

� presentación del estándar de documentación usado en la asignatura Comparación entre estándares de documentación y fases (workflows) de desarrollo

Fases Documentación USDP Clásica IEEE ESA ESA Lite

Requisitos User

Requirements Document

User Requirements Document

Análisis

Análisis de requisitos

Software Requirements Specification Sofware

Requirements Document

Diseño arquitectónico

Architectural Design Document

Diseño Diseño detallado

Sofware Design Document Detailed Design

Document

Software Specification Document

El Estándar de la ESA (documentos relevantes en negrita; ver web de la asignatura)

� GENERAL o ESA software engineering standards

� Explicación general de cada fase (Capítulos respectivos) � Plantillas de documentos (Apéndice C)

o Guide to the software engineering standards � PRODUCTS

o Guide to the user requirements definition phase o Guide to the software requirements definition phase o Guide to the software architectural design phase o Guide to the software detailed design and production phase o Guide to the software transfer phase o Guide to the software operations and maintenance phase

� PROCEDURES o Guide to software project management o Guide to software configuration management o Guide to software verification and validation o Guide to software quality assurance

� ESA Lite o Guide to applying the ESA software engineering standards to small software

projects o Guía para la aplicación de los estándares ESA de ingeniería de software a

proyectos de software pequeños

7

Los Requisitos de Usuario en el Estándar ESA � Guía general

o Plantilla C1 o Capítulo 2

� Entorno operacional (2.3.2) • Modelo de casos de uso

� Clasificación de los requisitos (2.3.3.1) • De capacidad: funciones y operaciones requeridas por los

usuarios • De restricción: restricciones en la construcción y operación del

software � Atributos de cada requisito (2.3.3.2)

• Identificador, necesidad, prioridad, estabilidad, fuente, claridad, verificabilidad

� Guía específica o Capítulo 2: especificación de requisitos o Capítulo 5: redacción del Documento de Requisitos de Usuario

Descripción de la práctica

� Sistema informático que implementa el juego del parchís � Libertad para escoger

o Plataforma: � ordenador de propósito general/ordenador específico � único ordenador con uno/varios terminales � varios ordenadores conectados en red/internet

o Interacción con el usuario: � teclado, joystick, pantalla táctil, etc.

Primera entrega de la práctica

� Semana 15-19 marzo o Cuatro grupos el primer día, cinco grupos el segundo día o Entrega del documento impreso: todos el primer día o Selección aleatoria del portavoz del grupo o Presentación en clase: 15 minutos máximo o Formato de presentación (5 transparencias máximo): cañón / acetato

� Semana 29 marzo-2 abril o Evaluación del documento y la presentación o Entrega del documento de evaluación impreso o Discusión del documento de evaluación por grupos

Esquema de calificación de la asignatura

� 50% Teoría o Examen de test: ¿por qué no conviene filtrar las preguntas? o Cada grupo propone tres preguntas, con sus correspondientes respuestas (3-4) o Se selecciona una pregunta de cada grupo para formar el examen + otras dos o 10% Nota correspondiente a la valoración de la pregunta (grupo) o 20% Nota del examen de test (individual) o 20% Nota correspondiente a la dificultad de la pregunta (grupo)

� 50% Práctica o 30% Documentos URD, SRD, ADD (documento final entregado único) o 10% Presentación URD, SRD, ADD o 10% Documentos de evaluaciones al otro grupo

8

3. Requisitos del usuario: interacción con el cliente

Fuentes � Braude, cap. 3, pp. 141-145

Objetivos

� Cómo identificar y entrevistar a los clientes Las fuentes de los requisitos (p141)

� Restricciones naturales (físicas, químicas, biológicas, sociológicas...) � Documentos (leyes, documentos organizativos de la empresa...) � Personas: deseos y necesidades

Identificación de stakeholders (interesados: usuarios, clientes, etc.) (p142)

� ¿Quiénes tienen interés en el producto? (Ejemplo: sitio web de comercio electrónico) o Los usuarios o Los propietarios o Los administradores o Los desarrolladores, incluso (si quieren probar nuevas tecnologías)

� ¿Quién es el cliente? o La persona que te contrata o El departamento de Marketing, que diseña un producto para un cliente ideal o Aplicaciones a medida, aplicaciones genéricas

� Los distintos interesados pueden tener intereses opuestos y generar requisitos contradictorios (¿puede un profesor ver el expediente académico de un alumno?)

o Ejemplo: El cliente de Aula Global es la Universidad, pero los usuarios principales son los profesores y alumnos, que no fueron consultados...

� Negociar el equilibrio requisitos-presupuesto-planificación: tarea del director del proyecto, que requiere habilidades de gestión, personales, negociadoras y políticas

� El cliente confía en el ingeniero de requisitos para aclarar sus necesidades (como un arquitecto)

� Trabajo conjunto para determinar los deseos del cliente: idea general, estudio del problema, descubrir matices, tomar decisiones clave

Entrevistas y documentación (p144)

� La entrevista es un recurso caro: consume un tiempo significativo de más de una persona � requiere una planificación cuidadosa

� Es importante escuchar con atención, pero no basta con escuchar, hay que saber preguntar, el cliente necesita ayuda: el resultado es producto del trabajo conjunto

� Escribir los requisitos y validarlos por escrito – continuar las reuniones hasta que se alcance el acuerdo

Cómo llevar adelante una entrevista (p144)

� Antes de la entrevista o Enumerar y priorizar los entrevistados o Planificar la hora de comienzo y finalización de cada entrevista o Asistir al menos dos personas del equipo de desarrollo: es preferible que haya

dos entrevistadores, uno sólo tiene a descuidar algunos puntos o Usar cinta grabadora (pedir permiso)

� Durante la entrevista o Concentrarse y escuchar

9

o No sea pasivo: preguntar y animar o Insistir hasta entender los deseos y las necesidades o Utilizar diagramas de casos de uso, flujos de datos, estados o Tomar notas detalladas o Concretar la siguiente entrevista

� Después de la entrevista o Redactar el borrador de requisitos o Revisar entre los dos entrevistadores o Enviar a los clientes para comentar y aprobar

10

4. Requisitos del usuario: obtención y descripción

Fuentes � Braude, cap. 3, pp. 145-165

Descripción de requisitos del cliente (p145)

� El gran desafío es averiguar y expresar claramente lo que los clientes quieren y necesitan

� A veces bastan las palabras, pero otras veces las figuras o tablas son de gran ayuda � El cliente suele tener una idea vaga, inconsciente e incompleta de lo que espera de su

aplicación (concepto de operaciones) � Diferentes personas pueden concebir de modo muy distinto lo que implica un sistema � Ejemplo: una “aplicación meteorológica” puede significar:

o Una utilidad para presentar gráficamente información recibida en bruto del servicio meteorológico

o Un sistema en tiempo real para predecir el tiempo o Una aplicación para alertar a los usuarios de anomalías climáticas

Técnicas para la obtención y descripción de requisitos del cliente

� Textuales: relativamente accesibles a un cliente sin formación específica o Texto en prosa común y corriente o Texto estructurado, lenguaje técnico o Casos de uso

� Gráficas: requieren un cierto grado de formación técnica en el cliente o Tienen el peligro de convertir el análisis de requisitos en diseño o Diagramas de flujo de datos o Diagramas de estados o Interfaces de usuario

� Prototipos Casos de uso (p145)

� Son una técnica para describir los requisitos como una interacción entre la aplicación y un agente externo al sistema

� Jacobson observó que, a pesar de enorme número de ejecuciones potenciales, la mayoría de las aplicaciones se conciben en términos de un número relativamente pequeño de interacciones típicas

� Los casos de uso de alto nivel expresan el punto de vista del cliente de cómo debe funcionar la aplicación (concepto de operación)

o Los casos de uso se pueden usar también a bajo nivel, para especificar los requisitos que debe cumplir un componente o subsistema, por ejemplo

o También pueden servir para desarrollar los planes de prueba � Por su forma de “historia” son útiles para comunicarse con los clientes (y describir o

descubrir requisitos): proporcionan una vista muy reveladora de la aplicación o Los conceptos empleados sirven para descubrir las clases de análisis o Por el mismo motivo, la descripción de historias es útil para ilustrar usos

típicos, pero es bastante limitada para especificar requisitos de modo completo o Por tanto, describir la “historia” debe ser un medio para llegar a determinar el

“contrato”: básicamente, mediante pre- y post- condiciones o Conclusión: de la interacción a la función

� Los estándares de documentación son anteriores a los casos de uso: adaptarlos � Pueden usarse con métodos orientados a objetos o con métodos estructurados

11

� Más adecuados para obtener requisitos funcionales que no-funcionales Diagramas de flujo de datos (p148)

� Para requisitos que se describan de modo natural como un flujo de datos (flechas) entre elementos de procesamiento (nodos)

� La utilidad de los DFD’s depende del tipo de aplicación Diagramas de estados (p149)

� Dividir la aplicación en estados de modo que siempre se encuentre exactamente en uno de ellos

� Útiles para aplicaciones dirigidas por eventos Interfaces de usuario (p151)

� Diseño de la interaz de usuario: ¿requisitos o diseño? � Visualizar la GUI ayuda a los clientes a concebir y describir la aplicación � Cuando se le muestran los bocetos, el cliente se da cuenta de que necesita más o que

quiere algo diferente � Tarea de un profesional especializado (especialmente el diseño detallado) � Once pasos para desarrollar la GUI (ver libro)

Prototipos (p161)

� Prototipo rápido o Implementación parcial, con un componente GUI importante o Muy útil para elicitar requisitos del cliente y para identificar y eliminar partes

arriesgadas de un proyecto o Una comprensión más profunda ahorra trabajos futuros de corrección

� El beneficio del prototipo depende de su coste y de su valor para el proyecto: inversión � Figura 3.34: inversión óptima, inversiones rentables � ¿Debe transformarse el prototipo en la aplicación? Decisión planificada, no accidental,

por que si no puede darse un empeoramiento de calidad o contruidos rápidamente, rara vez documentados o implementados en leguajes que rápidamente obtienen resultados, pero tal vez

inadecuados para la aplicación final: seguridad, fiabilidad o desventaja: el cliente puede impresionarse y pensar que estamos cerca del final o ¿transformarías un prototipo de casa con balas de paja en la casa final?

� Beneficios: extraer requisitos, ensayar soluciones Estudios de viabilidad (p164)

� ¿Merece la pena realizar el proyecto? � Implementaciones parciales (prototipos) o simulaciones

o Ej: videojuego por internet, [automatrícula por internet] � Prototipos y simulaciones son proyectos en sí mismos: requisitos, documentación, etc.

Actualización del proyecto para reflejar el análisis de los requisitos del cliente (p165)

� El conjunto de documentos está vivo, varios se ven afectados en cada fase, gestionarlos no es fácil

� La obtención de requisitos afecta a la planificación del proyecto. El proceso puede ser iterativo, pero con ciertos límites:

o El cliente quiere saber el coste antes de empezar o El desarrollador no quiere comprometerse al menos hasta congelar los

requisitos

12

� La mejor comprensión de los requisitos facilita refinar las estimaciones de esfuerzo necesario: planificación-presupuesto

� Números de versión de secciones y subsecciones del documento de Requisitos

13

5. Requisitos del software: tipos de requisitos

Fuentes � Braude, cap. 4, pp. 181-187

Significado de los Requisitos del Software (p182)

� Es el único lugar donde se pone por escrito la naturaleza exacta de la aplicación. Nivel de detalle debe ser completo, pero no redundante

� Son la base para el diseño y la implementación � Diversas denominaciones

o Requisitos específicos o Especificaciones funcionales o Requisitos del desarrollador / Requisitos detallados / Requisitos D o Requisitos del software

� Lista completa de propiedades específicas y funcionalidad que la aplicación debe poseer, expresada en el nivel de detalle final

o Cada requisito es numerado, etiquetado, y se le sigue la pista hasta la implementación

o Son consistentes y se elaboran sobre los Requisitos C � Audiencia primaria, el desarrollador. El cliente suele estar interesado en ellos y

típicamente es capaz de entenderlos y hacer observaciones � Anéctoda: en 1999 la NASA perdió un satélite porque se asumió que ciertos datos de

control estaban en unidades métricas en lugar de anglosajonas. El defecto se identificó pocos días después del desastre... (podía haberse identificado durante el análisis)

� No es una tarea estúpida: organizar todos los requisitos bien detallados es una tarea difícil que requiere saber organizar personas y documentación

Tipos de Requisitos D (clasificación también aplicable a los Req-C) (p184)

� Requisitos funcionales o Funcionalidad de la aplicación

� Requisitos no funcionales o Rendimiento

� Velocidad � Capacidad de tráfico � Uso de memoria (volátil, permanente; o: primaria, secundaria) � [Tiempo de respuesta] � [Líneas de atención simultánea]

o Fiabilidad y disponibilidad o Manejo de errores o Requisitos de interfaz

� Interacción de la aplicación con el usuario y con otras aplicaciones o Restricciones

� Exactitud, precisión � Restricciones de lenguaje y herramientas � Restricciones de diseño � Estándares de uso obligado (Ej.: guías de estilo GUI) � Plataformas hardware de uso obligado

o [Seguridad] � Requisitos inversos

o Lo que la aplicación no debe hacer

14

Requisitos funcionales (p184) � Especifican los servicios que la aplicación debe proporcionar � Ejemplo: un tiempo de respuesta no es un requisito funcional

Rendimiento (p185)

� Especifican restricciones temporales que la aplicación debe cumplir � Son negociables hasta cierto punto con el cliente � Son críticas en los sistemas de tiempo real

Fiabilidad y disponibilidad (p185)

� En estos dos factores se reconoce que las aplicaciones difícilmente son perfectas, pero sí se exige un nivel de calidad mínimo

� Fiabilidad: cuantifica los errores permisibles y su gravedad o Ejemplo: el sistema no sufrirá más de dos fallos de nivel uno al mes

� Disponibilidad cuantifica el grado de disponibilidad de la aplicación para los usuarios o Ejemplo: la aplicación no estará disponible como máximo durante 10 horas en

cualquier periodo de 30 días, y como máximo durante 2 horas seguidas Manejo de errores (p185)

� Cómo debe responder la aplicación a errores de su entorno, no a errores internos o Ejemplo: cómo reaccionar ante un mensaje en formato no reconocido

� No se debe abusar del manejo de errores internos, que no deben existir (no debemos cubrir nuestros errores con un código interminable de manejo de errores)

o Ejemplo: determinar lo que hay que hacer si una función es llamada con parámetros equivocados; esto sólo se debe hacer si es preferible a la terminación de la aplicación

Requisitos de interfaz (p186)

� Describen el formato con el que la aplicación se comunica con su entorno o Ejemplo (comunicación con usuarios): El coste del envío se mostrará en la

esquina inferior derecha o Ejemplo (comunicación con otras aplicaciones): Los pedidos se transmitirán en

formato XML utilizando la plantilla DTD detallada en el anexo IV Restricciones (p186)

� Describen límites o condiciones sobre cómo diseñar o implementar la aplicación � Estos requisitos no deben suplantar el proceso de diseño, simplemente especifican

condiciones impuestas en el proyecto por el cliente, el entorno, u otras circunstancias o Ejemplo (exactitud, precisión): las tarifas aplicadas se medirán en

diezmilésimas de euro o Ejemplo (lenguaje, herramienta): se empleará el lenguaje Fortran, el gestor de

base de datos SQLServer o Ejemplo (diseño): se emplearán tecnologías de intranet y cliente-servidor o Ejemplo (estándares): los informes generados se ajustarán al estándar XX-123 o Ejemplo (plataformas): la aplicación deberá funcionar sobre Windows 95

Requisitos inversos (p187)

� Lo que la aplicación no hará: son infinitos... � Seleccionar aquellos que sirven para aclarar los verdaderos requisitos y pueden aclarar

posibles malentendidos o Ejemplo: la aplicación de automatrícula no asesorará al alumno en las

asignaturas que le conviene escoger

15

6. Requisitos del software: propiedades deseables

Fuentes � Braude, cap. 4, pp. 187-196

Propiedades deseables de los Requisitos del Software

� Propiedades que deben tener todos los requisitos para no perder detalles del proyecto � Al inspeccionar los requisitos deben cuestionarse estas propiedades � Para manejar con mayor facilidad un requisito, deberá tener un tamaño adecuado: ni

tan grande que sea inmanejable, ni tan pequeño que no valga la pena seguirle la pista por separado

� Propiedades globales o Completitud o Consistencia

� Propiedades individuales o Trazabilidad o Comprobabilidad o Prioridad o Condiciones de error

Completitud (p194)

� Es difícil que los requisitos detallados sean totalmente auto-contenidos debido a las referencias mutuas.

� Completitud significa que no hay omisiones que comprometan la integridad de los requisitos.

� Para cada requisito, comprobar que los demás requisitos que deben acompañarlo están presentes.

Consistencia (p195)

� Ausencia de contradicciones entre requisitos. � Es más difícil de comprobar si el número de requisitos crece. � Una buena organización facilita la detección de contradicciones.

Trazabilidad de requisitos funcionales (p187)

� Es la correspondencia entre cada requisito y una o varias partes del diseño/implementación

� Es necesaria para poder comprobar que la aplicación satisface los requisitos � Es muy necesaria para afrontar que los requisitos cambian � Una forma de conseguirla es relacionar cada requisito D funcional con una función

específica en el lenguaje destino [pero esta técnica es poco generalizable y limitada; produce excesivo acoplamiento entre la estructura de los requisitos y la estructura de la implementación]

� En OO no es trivial preguntarse qué clase es responsable de qué función � Si la trazabilidad es difícil, los desarrolladores tenderán a evitar la actualización del

documento de requisitos al hacer cambios al código, por el excesivo trabajo: en consecuencia el documento de requisitos se hace inútil para las pruebas y la validación. Si además el documento no es fiable por culpa de algunos miembros del equipo menos responsables, entonces ni siquiera los más responsables se tomarán la molestia de mantenerlo al día. Por tanto, el sistema para hacer corresponder requisitos con diseño y código debe ser claro y concreto. Ejemplo: matriz de trazabilidad de requisitos.

16

� Un requisito puede corresponderse con varias partes del código (funciones), que a su vez pueden implementar varios requisitos cada una. Por tanto, antes de cambiar el código para adaptarse a un cambio en un requisito, hay que comprobar que otros requisitos no quedan comprometidos.

� La correspondencia Requisito-Función es muchos-a-muchos. Tal vez no pueda conseguirse que sea uno-a-uno, pero al menos puede intentarse que sea pocos-a-pocos.

� La trazabilidad es en ambas direcciones: Req-C � Req-D � Impl � Figura 4-8 (p190): correspondencias varias entre requisitos, elementos de diseño,

elementos de código, y unidades de prueba. Trazabilidad de requisitos no funcionales (p190)

� La correspondencia con elementos del diseño y de la implementación es mucho más difícil.

� Rendimiento: identificar los elementos que consumen más tiempo o memoria. La mayor parte de los recursos son consumidos por un número reducido de elementos, de modo que esta tarea es provechosa para mejorar el rendimiento. Una pista: bucles, gráficos y comunicaciones suelen ser los que más tiempo consumen.

� La validación normalmente requiere un mayor nivel de integración del sistema (no es fácil validar componentes aislados).

Comprobabilidad (p191)

� Validar: intentar descubrir y eliminar defectos en la implementación por medio de pruebas (no garantiza que todos los defectos desaparecen).

� Verificar: comprobar que los requisitos expresan lo que desea el cliente, y que el código implementa estos requisitos. (p46)

� Para validar y verificar un requisito es necesario que éste sea comprobable (testable). Un requisito que no es comprobable o que es ambiguo tiene escaso valor y debe ser rechazado.

o El sistema mostrará la diferencia entre el valor observado y la media mundial (no comprobable) � El sistema mostrará la diferencia entre el valor observado y el valor publicado por Naciones Unidas (¿Cuándo? Ambiguo) � El sistema mostrará la diferencia entre el valor observado y el último valor publicado por Naciones Unidas en su página web.

� Esbozar una prueba específica que establecería la satisfacción � Asegurar que no es ambiguo, ni siquiera interpretando mal a propósito

Prioridad (p191)

� Para negociar entre funcionalidad, planificación, presupuesto y nivel de calidad, es conveniente que los requisitos funcionales tengan prioridad asignada, por ejemplo, tres o cuatro categorías: esencial, deseable, opcional.

� Si el 20% de la aplicación proporciona el 80% de su valor... no más del 20% de los requisitos deberían ser “esenciales”.

Condiciones de error (p195)

� Para estar completa, la especificación del requisito debe tener en cuenta las condiciones de error, es decir, qué ocurre con el requisito en una situación con errores.

� Las condiciones de error son especialmente importantes para realizar las pruebas, ya que al probar un requisito se fuerzan condiciones de error, y es necesario prever qué debe ocurrir en estos casos. Caso típico: datos de entrada incorrectos.

� Ejemplo: clasificar un triángulo a partir de las coordenadas de sus tres vértices. � No confiar en que no se producirán condiciones de error: esto aumenta la dependencia

entre módulos (un módulo confía en la detección de errores de otro módulo).

17

� Redundancia para promover la seguridad. � Determinar lo que hay que hacer en situaciones no previstas � Prevenir posibles errores de programación en lugares críticos

Para escribir un requisito: resumen

� Enunciado breve del mismo, numerado � Explicación detallada � Propiedades tal como se han discutido hasta aquí, por ejemplo

o Prioridad o Condiciones de error o Pruebas de validación

� Referencias a otros requisitos � Trazas hacia requisitos de usuario y hacia diseño/implementación

Para cualquier labor de escritura

� Tenga siempre a mano diccionarios (normal, sinónimos, estilo, idiomas, corrector ortográfico y sintáctico)

� Escribir, corregir, escribir, corregir… y hacerlo entre varios (uno escribe, otro corrige) � Respetar normas ortográficas, sintácticas, gramaticales, estilísticas… no es un

capricho: lo que no está bien escrito no se entiende � Estructurar bien, proceder con orden, proporcionar las referencias necesarias � Sintetizar, resaltar ideas importantes, resaltar más lo menos obvio

18

7. Requisitos del software: organización y calidad

Fuentes � Braude, cap. 4, pp. 200-217

ORGANIZACIÓN Métodos para organizar los Requisitos Específicos (p201)

� Una buena organización de los RS es esencial, porque si no están organizados no se pueden manejar (localizar, actualizar, aplicar, comprobar...)

� Esquemas de organización: o Por funcionalidad o servicio requerido tal como es percibido desde fuera,

normalmente definido como pares estímulo-respuesta (operaciones del sistema). Se aplica la descomposición jerárquica (descomponer la aplicación en un conjunto de funciones de alto nivel, y éstas en sub-funciones, etc.): forma más tradicional de organizar los requisitos.

o Por caso de uso, es decir, por secuencias operacionales, o usos coordinados de funcionalidades de acuerdo con un objetivo: favorecida por USDP.

o Por clase: estilo OO explicado más abajo, descomponer la aplicación en unidades atómicas de información y comportamiento.

o Por estado (especificando los requisitos específicos que se aplican a cada estado): en cada estado se enumeran los eventos que afectan a la aplicación. Útil si los requisitos son muy distintos en cada estado. Ejemplos: aplicación contable, estados Configuración, Ejecución, Respaldo; aplicación radar, estados entrenamiento, normal y emergencia.

� Conviene que el esquema de organización esté relacionado con la probable arquitectura del sistema (oo, funcional, etc), para facilitar la trazabilidad.

Organización de los requisitos por casos de uso (p203)

� Usar el diagrama de casos de uso como índice de los requisitos � USDP explota la observación de que muchos requisitos surgen de modo natural en

secuencias operacionales. � Ejemplo, el requisito de que una aplicación de videoclub permitirá introducir el título

de un nuevo video típicamente surge como parte de una secuencia de transacciones. Organización de los requisitos en clases (p203)

� Usar el diagrama de clases como índice de los requisitos � Las clases resultantes de la organización de los requisitos pueden tener mucho o nada

que ver con las clases del diseño y la implementación. o Ventajas de una relación estrecha: trazabilidad, una de las banderas de la OO.

Las clases próximas a conceptos del mundo real es más probable que sean reutilizadas.

o Desventajas: acoplamiento análisis-diseño, selección de clases de diseño antes de tiempo.

� Procedimiento: o Identificar y enumerar las clases del dominio: las que pertenecen

específicamente a la aplicación, al problema en cuestión. � El objetivo es identificar un conjunto mínimo pero suficiente de clases

de dominio que incluyan todos los requisitos específicos. � Inspeccionar los requisitos del cliente para identificar clases. � Los casos de uso son una fuente importante para identificar clases.

19

o Para cada clase, poner por escrito la funcionalidad requerida de la aplicación que pertenezca principalmente a esa clase, en forma de atributos y funciones.

� Atributos: unidades de información � Operaciones: unidades de comportamiento, reacciones frente a eventos

(es mucho más fácil repartir los atributos que repartir las operaciones) � Existencia requerida de objetos individuales de la clase � Diseñar al mismo tiempo los planes de prueba

� Usar lenguaje natural, no pseudo-código, para nombres de atributos y funciones. � Numeración decimal para las clases y cada uno de sus atributos y funciones

requeridos. (p210) Cómo seleccionar la clase correcta para cada requisito (p210)

� Lo más difícil es decidir en qué clase se va a situar un requisito dado. � Fácil cuando se trata de el nombre de una entidad, por ejemplo. � Difícil cuando se trata de un evento u operación que implica a varias entidades

Conexión con la documentación de pruebas (p211)

� Las pruebas deben/deberían (comenzar a) escribirse a la vez que los requisitos: � Esto ayuda a clarificar el sentido de cada requisito � Desplaza parte del trabajo de la fase de pruebas a la fase de requisitos, aliviando así

parte de la presión que se sufre en la segunda mitad del proyecto, cuando el tiempo es menos flexible.

Uso de herramientas para el análisis de requisitos (p217)

� Las herramientas pueden ayudar a o capturar y gestionar los requisitos, por ejemplo mediante ordenación,

priorización, asignación y seguimiento; o valorar el estado del análisis de requisitos.

� La información de seguimiento puede presentarse en una hoja de cálculo vía web, con hipervínculos a los documentos relevantes del proyecto.

� Los hipervínculos ayudan a evitar la duplicitad de información: por ejemplo, la doble especificación de un requisito – poner en el código un hiperenlace al documento de requisitos donde se especifica el requisito implementado.

CALIDAD Garantía de calidad en el análsis de requisitos específicos (p212)

� Estándar de Planificación de la Garantía de Calidad (IEEE Quality Assurance Planning, standard 730.1-1995)

� Los requisitos deben cumplir determinados criterios de calidad, por ejemplo: o Esquema de identificación unívoca de requisitos o Trazabilidad o Uso de lenguajes formales para la definición de requisitos

� Si no se exige que los requisitos cumplan los criterios de calidad, entonces más adelante no se podrá comprobar que la aplicación satisface estos mismos requisitos (es decir, no se podrá buscar la calidad en fases posteriores del proyecto).

� Cada medición (o métrica) tiene un coste en dinero y tiempo para obtenerla, almacenarla, analizarla e informar acerca de ella. Se trata de optimizar la relación coste/beneficio, lo cual depende de muchos factores: cultura de la organización, estado del proyecto, naturaleza del proyecto, etc. No se trata de obtener mediciones sin saber para qué. Idea general: clasificar las mediciones en tres categorías (bien, regular, mal).

20

� Estas medidas son útiles cuando sus valores esperados se especifican por adelantado. Por ejemplo, basados en experiencias anteriores, establecer que los requisitos se consideran completoscuando la tasa de modificación y adición es menor del 1% semanal.

Algunas métricas (medidas) de calidad: cómo de bien están escritos los requisitos (p213)

� Porcentaje de requisitos específicos no ambiguos � Grado de completitud � Porcentaje de requisitos mal clasificados (asignados a una clase equivocada) � Porcentaje de requisitos que no son

o Comprobables o Trazables o Priorizados o Atómicos o Consistentes con el resto de requisitos

� Medidas de la efectividad de la inspección de requisitos o Porcentaje de requisitos que faltan o son defectuosos, encontrados por hora de

inspección � Medidas de la efectividad del proceso de análisis de requisitos

o Coste por requisito específico � Coste medio total (tiempo total / número de requisitos) � Coste marginal (coste de obtener uno más) � Ritmo al que los requisitos son: modificados / eiminados / añadidos

� Medida del grado de completitud de los requisitos o Estimado, después de la terminación oficial de la obtención de requisitos

específicos, a partir del ritmo al que los requisitos específicos son modificados o añadidos (probablemente es imposible en la práctica decir cuál es el “último” requisito)

21

8. Diseño arquitectónico: descomposición, marcos y patrones

Fuentes � Braude, cap. 5, pp. 247-263

Introducción a la arquitectura del software (p248)

� Analogía: proceso de construcción de un puente... o Análisis de requisitos � decidir dónde debe comenzar y terminar el puente, y

qué tipo de cargas debe soportar o Diseño arquitectónico � elegir entre puente colgante, puente volado, puente

tensado, u otro tipo que satisfaga los requisitos: esto son arquitecturas de puente (elegir un estilo arquitectónico es elegir un tipo de solución)

� Los ingenieros software se enfrentan a un proceso de decisiones similar � Arquitectura del software = “diseño arquitectónico” = “diseño de alto nivel”

o Distinta de: “diseño detallado” = “diseño de bajo nivel” � Diseño � encontrar soluciones a problemas complejos

o Fundamentalmente mediante la descomposición de la solución o Arquitectura = tipos de elementos en la solución, tipos de relaciones entre ellos

� Las arquitecturas limpias y elegantes facilitan implementaciones libres de defectos y son más fáciles de extender y reutilizar

� Aunque tenga mucho de arte, la arquitectura de software debe superar la inmadurez o Antes: creación de diseños ad hoc a partir de la nada, reutilización de diseños

encontrados por casualidad o Ahora: diseño metódico y disciplinado

� El diseño de software metódico y disciplinado consiste en descomponer la solución en elementos y relaciones entre elementos (metódico, pero no automatizable...)

� La arquitectura no se refiere sólo a la distribución del software entre las partes físicas, sino también a la descomposición del software en módulos relacionados entre sí

� La especificación clara de arquitecturas software, importante para todas las aplicaciones, es indispensable en el trabajo en equipo: modularización y ensamblaje

Criterios para la selección de una arquitectura (p250)

� Para un proyecto software dado puede haber varias arquitecturas apropiadas � Se elige una teniendo en cuenta los objetivos, que deben estar priorizados ya que unas

arquitecturas satisfacen mejor unos objetivos que otros (fig. 5.5): o Extensión: facilitar la adición de nuevas caracterísiticas (features)

� Hace más complejo el diseño � Aporta mayor grado de abstracción � Ejemplo: arquitectura que soporte no este juego de tablero particular,

sino cualquier tipo de juego de tablero � Generalizar requiere invertir tiempo en el diseño: decidir qué tipo de

extensiones pueden surgir, etc. La distinción de requisitos opcionales/deseables es útil aquí, ya que señala hacia dónde apunta el desarrollo del sistema

o Cambio: facilitar el cambio de requisitos � Es distinto del anterior, aunque requiera técnicas similares � Ejemplo. Encounter: posibilidad de perder el control del personaje

o Simplicidad: hacer fácil de entender, hacer fácil de implementar � Difícil de coordinar con los dos anteriores

o Eficiencia: lograr alta velocidad o pequeño tamaño

22

Descomposición modular recursiva (p251) � No es difícil escribir pequeños programas. � El principal problema de las aplicaciones grandes es la complejidad: no tanto el

número de líneas de código, sino sus interrelaciones. � La mejor arma contra la complejidad es la descomposición modular, de tal forma que

cada módulo sea como un pequeño programa, también en su grado de dificultad. � Una buena descomposición modular es de importancia crítica, y lograrla constituye

un reto de primer orden para el diseño. � La descomposición debe ser recursiva: los módulos se descomponen a su vez � Descomposición modular eficaz: máxima cohesión, mínimo acoplamiento (fig. 5.6):

o Cohesión dentro de un módulo: grado de comunicación entre sus elementos. o Acoplamiento: grado de comunicación entre módulos diferentes.

� Estas dos características (alta intra-cohesión, bajo inter-acoplamiento = minimizar dependencias) hacen la arquitectura mucho más fácil de modificar, ya que los cambios tienen sólo efectos locales.

� Cada módulo/paquete debe contener un número pequeño de submódulos/subpaquetes (orientativo: 7±2), tanto en proyectos grandes como pequeños. Los proyectos grandes se distinguen porque el número de niveles de anidamiento es mayor, no por tener más submódulos en cada módulo.

� Ejemplo. Encounter: entorno, control, participantes, artefactos. � La descomposición perfecta es difícil, y no sólo en ingeniería del sofware. Ejemplo: el

requisito de ajustar en un espacio pequeño los componentes de un aparato electrónico puede establecer fuertes dependencias entre ellos.

� Diseño arquitectónico = primer nivel de descomposición: elegir componentes/módulos y relaciones entre ellos

Introducción a los marcos (frameworks) (p257)

� Al inventar el modelo de clases puede ser recomendable desarrollar o utilizar una colección de software preexistente que forma la base de una familia de aplicaciones similares: esta colección es lo que llamamos un marco (framework).

� Un marco es una colección de clases, normalmente interrelacionadas e incluidas en un paquete, que pueden ser usadas por varias aplicaciones diferentes. Las clases de un marco pueden ser abstractas, es decir, pensadas para usarse sólo a través de herencia.

� La aplicación se descompone en paquetes marco y paquetes de aplicación que los usan (fig. 5.12 y 5.13)

� Ejemplo: Java Application Programming Interface (API) o Los paquetes de la aplicación se relacionan con los paquetes marco a través de

herencia o agregación (en realidad asociación, o tipado). o Java Abstract Windowing Toolkit: el paquete awt no se modifica al usarlo, sino

que las clases propias de la aplicación heredan de clases awt, o agregan objetos awt en forma de atributos.

� Los marcos pueden ser de propósito general o específico: o General: sirven para un rango de aplicaciones muy variado (Java API) o Específico: desarrollados a la vez que una aplicación determinada, sólo

servirán normalmente para aplicaciones muy semejantes. � Algunos creen que los marcos sólo deberían desarrollarse si van a ser usados por un

gran número de aplicaciones. No obstante, también hay ventajas en desarrollar un marco parcial en paralelo con una aplicación, aunque no vaya a ser empleado en muchas otras aplicaciones.

� Ejemplos de marcos específicos: o Encounter: marco para juegos de rol en general. o Parchís: marco para juegos de tablero y fichas.

23

Introducción a los patrones de diseño (p260)

� En lugar de reinventar la rueda, intentamos reutilizar diseños que hayan demostrado su eficacia en previas aplicaciones. Los patrones de diseño son combinaciones de clases y métodos interrelacionados que la experiencia ha demostrado que resuelven ciertos problemas comunes de diseño.

� Ejemplo: colección de clases que implementan un árbol de objetos. � Analogía: el patrón “rancho” para casas aisladas con gran extensión de terreno. El

“rancho” es una idea de diseño que permite muchas realizaciones alternativas: no es un conjunto inalterable de planos de construcción.

� Gamma et al. difudieron los patrones de diseño entre el público con su ya clásico libro, en el que introducen 23 patrones divididos en patrones de estructura, de creación y de comportamiento. Naturalmente, puede haber más, inventados por otros autores.

o Patrones de estructura: formas de representar conjuntos de objetos, donde el cojunto puede ser tratado de manera elegante como una única entidad. Ejemplo: árboles y listas enlazadas.

o Patrones de creación: formas de crear objetos complejos como árboles o redes. o Patrones de comportamiento: formas de capturar el comportamiento de

objetos, por ejemplo, recorriendo colecciones de objetos en determinado orden. � Son aplicables tanto a nivel de diseño arquitectónico como a nivel de diseño detallado. � Algunos patrones son particularmente útiles en el nivel arquitectónico (fig. 5.17). � No conviene usarlos para las clases de dominio (análisis), ya que éstas deben ajustarse

lo más posible a los requisitos, sin incluir “soluciones” (diseño). � Funcionamiento:

o Cada patrón de diseño presta un servicio específico requerido por un cliente: el patrón ejecuta el código necesario sin que el cliente tenga que conocerlo, y este código utiliza la estructura definida en el patrón

o El patrón de diseño define un punto de entrada para el cliente (habitualmente uno o varios métodos de una clase dentro del patrón).

o También existe el “código de puesta a punto”, que inicializa el estado del patrón, y hace posible que los clientes conozcan lo menos posible de la estructura interna del patrón de diseño.

Marcos y patrones

� Marco: conjunto de clases reutilizable, librería o reutilizar desarrollos

� Patrón: estructura que proporciona una determinada función o reutilizar ideas

� Relación entre ambos: o Los marcos implementan patrones o Los marcos pueden implementar otras ideas que no sean “patrones” o Los patrones pueden implementarse directamente sin usar marcos

24

9. Diseño arquitectónico: estilos arquitectónicos (1 y 2)

Fuentes � Braude, cap. 5, pp. 263-281

Clasificación de arquitecturas según Shaw & Garlan (p260) (fig. 5.16)

o Estas arquitecturas pueden ser adecuadas para un problema dado, o al menos pueden dar ideas para la modularización.

� Flujo de datos o Secuencial por lotes o Tuberías y filtros

� Componentes independientes o Procesos paralelos o Sistemas cliente-servidor o Sistemas de eventos

� Máquinas virtuales o Intérpretes o Sistemas basados en reglas

� Repositorios o Bases de datos o Sistemas hipertexto o Pizarras

� Arquitecturas en capas Arquitecturas de flujo de datos (dataflow architectures) (p263)

� Adecuadas para aplicaciones que se entienden mejor en términos de datos que fluyen entre unidades de procesamiento. Procesamiento distribuido con serialización.

� Los DFDs ilustran esta perspectiva. o Cada unidad de procesamiento es diseñada independientemente de las otras. o Los datos tienen una fuente/origen y terminan en un sumidero/destino. o Ejemplo: aplicación de banca (fig. 5.19).

� Dos subtipos concretos de arquitectura de flujo de datos: o “Tubería y filtro” (pipe and filter) (fig. 5.20, 5.21)

� Los elementos de proceso (filtros) aceptan una corriente de entrada (secuencia de elementos de datos uniformes) en cualquier momento, y producen corrientes de salida.

� Cada filtro debe ser independiente de los otros. � Ventajas: modularidad.

o Secuencial por lotes (batch sequential) (fig. 5.22) � Los filtros trabajan con lotes de datos, y la transacción típicamente

implica el procesamiento del lote completo, en contraste con el procesamiento continuo de la arquitectura pipe and filter.

� No hay correspondencia inmediata entre DFDs y modelos de clases, pero a menudo es posible convertir unidades funcionales en un DFD en métodos de clase (fig. 5.21).

� Ha sido la forma más común de expresar arquitecturas, y no desaparecerá de inmediato. Desventajas generales de los DFDs: no se corresponden fácilmente con el código, sea OO o de otro tipo.

Arquitecturas de componentes independientes (p262)

� Consiste en componentes que operan en paralelo (en principio) y se comunican entre ellos de tiempo en tiempo.

25

� Ejemplo: WWW, con miles de servidores y millones de navegadores. � Tres subtipos importantes (y ejemplos de aplicación de patrones de diseño):

o Cliente-Servidor / Patron de diseño Facade o Procesos Paralelos / Patrón de diseño Observer o Sistema de Eventos / Patrón de diseño State

Arquitectura cliente-servidor (p266)

� El componente servidor sirve las necesidades del cliente, expresadas como peticiones. � Ventaja: bajo acoplamiento. � La relación c/s es muy natural en ingeniería del software con equipos de trabajo

separados: diferentes paquetes de clases encargados a personas o grupos de desarrollo distintos, con relaciones c/s entre paquetes.

� No es necesario que los módulos software se encuentren en partes hardware distintas. � Problema: los servicios requeridos se encuentran en distintos estadios de desarrollo a

medida que progresa el proyecto. � Un componente actúa más eficazmente como servidor cuando su interfaz es

“estrecha”, es decir, la interfaz (básicamente, una colección de funciones) no contiene partes innecesarias, está recogida en un único sitio, y está claramente definida.

� El patrón de diseño Facade establece precisamente una interfaz “estrecha” con un paquete de clases. Regula la comunicación con los objetos del paquete, exponiendo tan sólo una de las clases del paquete al cliente, y escondiendo las demás (fig. 5.23).

o Una llamada que se referiría a un objeto dentro del paquete es sustituida por una llamada a un método del objeto fachada, que a su vez se referirá al objeto en cuestión.

o El patrón Facade prohíbe incluso mencionar las otras clases miembros del paquete en los clientes (se corresponde con el uso de clases públicas y privadas dentro del paquete).

o Esto en ocasiones puede ser una restricción demasiado severa, lo que puede indicar que el uso del patrón no es conveniente en ese caso.

Arquitectura de procesos paralelos (parallel comunicating processors) (p268)

� Los componentes son varios procesos se ejecutan en paralelo (threads en Java). � Esta arquitectura debe usarse si resulta más natural que el modelado sin paralelismo. � UML: objetos activos (procesos paralelos) y comunicaciones asíncronos (fig. 5.25). � El patrón de diseño Observer es adecuado para representar un tipo frecuente de

arquitectura en el que una fuente de datos independiente es mostrada de diferentes formas por varios clientes-observadores, que deben ser actualizados siempre que cambien los datos. Ejemplos: empresa de hamburguesas; indicadores de trenes.

o Funcionamiento (fig. 5.26): � Cliente pide a fuente que notifique a observadores (source.notify) � Fuente notifica a todos los observadores (* observer.update) � Cada observador concreto se actualiza a su manera (implementación

concreta de update), probablemente interrogando a la fuente concreta � La fuente concreta no conoce a los observadores concretos, sólo a los

observadores genéricos: aplicación del polimorfismo � Permite añadir y quitar observadores sin molestar a los demás � No es necesario que los observadores se ejecuten periódicamente

o El patrón es menos ventajoso si pocos observadores deben reaccionar (las numerosas notificaciones malgastan recursos), o si es más natural que los observadores pregunten espontáneamente, o si los distintos observadores tienen poco en común

26

Arquitectura de sistema de eventos (p270) � En esta arquitectura la aplicación es un conjunto de componentes que esperan a que

ocurra un evento que les afecte. � Ejemplos: procesador de textos, aplicación interactiva en general. � El patrón de diseño State facilita el modelado de un sistema con transiciones entre

estados, facilitando la adición de nuevos estados y acciones a medida que el sistema se desarrolla, sin perturbar el diseño existente.

o Resuelve el problema de cómo usar un objeto sin conocer su estado. o Las peticiones de servicio al objeto no implican conocer en qué estado se

encuentra, ya que éste las remite por delegación a objetos asociados que manejan esas peticiones de modo diferente según el estado que representen: a ejecución de acciones, transición a un nuevo estado, etc. (fig. 5.28).

o Atención: cada estado es una subclase, no una instancia. o Aplicación a Encounter (fig. 5.29).

Arquitectura de máquina virtual (p272)

� En esta arquitectura cada aplicación es tratada como un programa escrito en un lenguaje especial, que es interpretado y ejecutado en la máquina virtual.

� Como hay que construir un intérprete de este lenguaje, esta arquitectura rinde más si hay que escribir varios “programas” en él, para generar varias aplicaciones.

� Ejemplo: intérprete de instrucciones de ensamblaje de ordenadores (fig. 5.30). � Ventaja: facilidad de generar nuevas aplicaciones en el lenguaje de propósito especial. � Patrón de diseño Interpreter (fig. 5.31).

o La máquina virtual requiere la construcción de un intérprete, que interpreta expresiones (programas completos, partes de programa, expresiones primitivas, etc.).

o El patrón Interpreter es útil para interpretar expresiones complejas de modo recursivo: una expresión es simple o compuesta, y así una y otra vez.

o Adecuada para gramáticas pequeñas y velocidad poco relevante. � Esta arquitectura puede ser ventajosa para el procesamiento de scripts, escritos en un

lenguaje accesible para usuarios de formación media. Arquitectura de repositorio (p276)

� Es una arquitectura contruida principalmente en torno a los datos. � Ejemplos:

o Sistema de transacciones contra una base de datos. o Entornos de desarrollo interactivos (IDEs). o Editores de texto, aplicaciones ofimáticas. o Arquitecturas de pizarra para inteligencia artificial. o Hipertexto. o Repositorio (en sentido restringido): acceso uniforme a una colección de BD

� Es adecuada cuando el procesamiento es despreciable frente al formateado y almacenamiento de los datos.

� Peligro: que haya una gran candidad de procesamiento escondido entre los datos; complicar la base de datos con procedimientos ad hoc almacenados que pervierten el diseño limpio de la aplicación.

� Patrón de diseño Iterator o Es adecuado cuando los objetos de una colección o agregado deben ser

visitados de varias formas distintas. o Ejemplo: árbol de organización de una empresa; recorrer la empresa para

imprimir el nombre de los empleados, transferir su foto a un fichero, etc. o Operaciones elementales y cómo usarlas en un bucle (fig. 5.34 y 5.35)

27

Arquitectura en capas o niveles (layered architectures) (p278)

� Una capa arquitectónica es una colección coherente de artefactos software, típicamente un paquete de clases. En su forma más común, una capa usa como mucho otra capa, y es usada como mucho por otra más.

� La construcción de aplicaciones en capas puede simplificar (o complicar) el trabajo. � Reutilización: las capas pueden diseñarse para servir a varias aplicaciones (marcos). � Ejemplo: Encounter (fig. 5.36). � La arquitectura c/s es un tipo de arquitectura en capas. Problema: alto grado de

interdependencia. Solución: insertar una capa intermedia que las aísle. La capa intermedia puede seleccionar dinámicamente un servidor entre varios, por ejemplo. O bien, separar interfaz, negocio, datos.

Uso combinado de arquitecturas (p281)

� Es normal que una misma aplicación use distintas arquitecturas para resolver distintos aspectos del mismo problema.

� Ejemplo: Encounter o Base de datos para Artefactos o Procesos paralelos para los Personajes o Sistema de eventos para el Control General

� Las distintas arquitecturas estudiadas tienen muchos puntos en común: o máquina virtual � arquitectura multicapa o repositorio de datos � cliente-servidor o sistema de eventos � procesos paralelos o etc.

El documento de diseño arquitectónico en el estándar ESA

28

10. Diseño detallado: técnicas generales

Fuentes � Braude, cap. 6, pp. 302-342

Introducción al diseño detallado (“diseño de bajo nivel”) (p303)

� Un diseño elegante mejora la implementación y el mantenimiento de una aplicación. � El diseño detallado es la actividad técnica que sigue a la selección de arquitectura. Su

objetivo es dejar el proyecto preparado para la implementación. � El diseño detallado parte de los resultados de la fase de arquitectura, y termina con un

diseño completo y listo para la fase de programación. � Es decir, los programadores deberían ser capaces implementar un diseño detallado,

concentrándose en cuestiones puramente de codificación. � Conviene comenzar el diseño detallado por los aspectos que presentan mayores

riesgos. Dos técnicas generales de diseño (p308)

� Diseño por contratos (design by contract) o Diseñar contra una interfaz es como emplear un contrato: el proveedor de la

funcionalidad requerida (una clase, por ejemplo) se compromete a proporcionar funciones con determinada firma (signature), de modo que sus clientes pueden ser diseñados sin saber cómo se implementa la funcionalidad.

o El uso de interfaces (o clases abstractas) facilita la incorporación de otros subtipos concretos al diseño sin tener que cambiar el código cliente. Muchos patrones de diseño emplean la división entre capa abstracta y capa concreta.

o Además de la definición sintáctica (especificada mediante la signatura o firma), para un contrato también tiene interés la definición semántica (especificada mediante pre- y post- condiciones, u otros medios).

� Reutilización de componentes o La mala costumbre de “reinventar la rueda” en ingeniería del software impide

su desarrollo como disciplina de ingeniería. Una posible razón: organización inadecuada de arquitecturas, diseños y código, que hace casi imposible la reutilización. El uso de tecnologías de objetos y componentes facilita la reutilización: Microsoft MFC, controles VB, objetos COM, Java Beans, etc.

o Elección de un componente: � ¿está documentado tanto como el resto de la aplicación? � ¿hay que adaptar el componente o la aplicación para poder usarlo? � ¿ha sido probado tanto como el resto de la aplicación?

o Reutilizar tanto desarrollos (marcos, componentes) como ideas (patrones). Especificación de clases en diseño de bajo nivel (p312)

� Atributos y métodos o Atributos y métodos que provienen directamente de los requisitos software o Otros atributos y métodos requeridos por el diseño arquitectónico y detallado o Especificación completa: visibilidad, valores iniciales, firma, etc. o Usar diagramas de comportamiento para determinar con exactitud los métodos

necesarios: interacción (colaboración, secuencia), actividad, estados. � Invariantes de clase

o Un invariante es una aserción que debe mantenerse verdadera tras la ejecución de cualquier operación.

o Se presentan en forma de restricciones que deben cumplir los atributos.

29

o Pueden proceder de los requisitos o del diseño. � Invariantes de función: pre- y post- condiciones

o Son asertos acerca de relaciones entre variables que las funciones deben obedecer.

o Precondiciones: relaciones entre variables y constantes que se supone existen antes de la ejecución de la función.

o Postcondiciones: estas relaciones después de la ejecución. o Ejemplo: money withdrawal (fig. 6.19)

Especificación de algoritmos (p315)

� Es necesario estudiar el algoritmo antes de programarlo, especialmente si hay ramificaciones, iteraciones o interacciones (son cosas distintas) complejas, para que las complejidades del lenguaje de programación no oculten u oscurezcan errores algorítmicos. Dos técnicas clásicas:

� Diagrama de actividad (diagrama de flujo de control). o Hay herramientas de ingeniería inversa, pero tiene más interés la ingenieria

directa, es decir, detectar los errores antes de programarlos. o Utilidad para lograr un anidamiento correcto en las estructuras de control y

evitar código spaghetti. o Hay que tener en cuenta que la orientación a objetos reduce en buena medida

la complejidad de la ramificación, al sustituirla por interacción entre objetos y polimorfismo (ramificación implícita), lo que en cierta medida reduce la utilidad de este tipo de diagramas.

� Pseudocódigo. o Especificación textual sin detalles del lenguaje de programación. o Ventajas: un nivel más de estudio, inspección, seguridad, disciplina. o Desventajas: más trabajo, nuevas posibilidades de error.

30

11. Diseño detallado: patrones de diseño (1 y 2)

Fuentes � Gamma, cap. 1, pp. 1-31; Abstract Factory (p87); Decorator (p175); Command (p233)

Qué es un patrón de diseño (p2)

� Un patrón describe un problema recurrente, y el núcleo de la solución a ese problema, de forma tal que se puede usar esta solución muchas veces sin hacerlo nunca de la misma manera.

� En general, un patrón consta de cuatro elementos esenciales: o Nombre: para incrementar nuestro vocabulario de diseño o Problema: describe cuándo aplicar el patrón, el problema y su contexto; por

ejemplo, una estructura de clases que revela un diseño inflexible o Solución: describe los elementos de que consta el diseño, sus relaciones,

responsabilidades y colaboraciones; no describe un diseño concreo, sino una plantilla (template) que puede aplicarse en muchas situaciones

o Consecuencias: balance de costes y beneficios de la aplicación del patrón � Los patrones son: descripciones de la estructura, comportamiento y comunicación de

un grupo de objetos y clases que resuelven un problema general de diseño y que

deben adaptarse a cada contexto particular. � Los patrones no son:

o Diseños codificados y encapsulados en clases reutilizables, como listas enlazadas o tablas hash � eso son herramientas o utilidades (toolkits), que pueden implementar patrones

o Diseños complejos específicos de un dominio concreto para una aplicación o subsistema � eso son marcos (frameworks), que pueden usar patrones

El catálogo de patrones de diseño (p8) (ver también fig. 1.1, p12)

Creación Estructura Comportamiento Abstract Factory Builder Factory Method Prototype Singleton

Adapter Bridge Composite Decorator Façade Flyweight Proxy

Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor

Cómo resolver problemas con patrones de diseño (p11)

� Idea general: diseñar para el cambio, reducir dependencias, incrementar flexibilidad � Programar teniendo en cuenta la interfaz, no la implementación

o Esto reduce el acoplamiento entre el cliente y su proveedor, la clase concreta utilizada, ya que una interfaz puede ser realizada por muchas clases distintas

� Preferir el uso de asociaciones (descomposición, según Gamma) frente a la herencia o Herencia: reutilización de caja-blanca (fuerte dependencia de la superclase) o Asociación: reutilización de caja-negra (débil dependencia entre clases)

31

� Emplear el mecanismo de delegación o Un objeto delega en otro la respuesta a una operación, análogamente a como

una subclase delega en la superclase la implementación o El equilibrio se desplaza:

� de la estructura estática en tiempo de compilación (generalizaciones) a la estructura dinámica en tiempo de ejecución (asociaciones)

� mayor flexibilidad � mayor complejidad y dificultad para entender la estructura � menor eficiencia de ejecución � conclusión: utilizar si simplifica más que complica

o Ejemplo: heredar un algoritmo de ordenación; delegarlo a un objeto enlazado Patrones de creación: Abstract Factory (p87)

� Propósito: proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.

� Ejemplos: o Editor de documentos adaptable a distintos estándares de apariencia o Juegos con representación 2D o 3D o Diseño de interiores: mobiliario de una cocina

� Problema: o El cliente usa una familia de objetos relacionados o Se desea flexibilizar el diseño para que sea fácil cambiar de una familia a otra o La estructura de la familia es común en todas las familias: cambia el tipo de

familia, pero no la forma de usarla (interfaz); cada familia representa un “estilo” diferente para objetos conceptualmente iguales

� Solución: o Se define una interfaz para cada objeto o producto de la familia: el cliente

conoce esta interfaz, pero no la clase concreta utilizada o Cada familia tiene una factoría de objetos asociada; las distintas factorías de

objetos tienen también una interfaz común o Se crea una factoría concreta (instancia de la subclase concreta; patrón

Singleton); es fácil cambiarla en tiempo de ejecución; la factoría escogida determina la familia entera, estilo de presentación, etc.

o En lugar de usar los constructores concretos (que requerirían mencionar las clases concretas), la factoría proporciona una interfaz uniforme para la creación de objetos de todas las familias

� Consecuencias: o (+)El cliente manipula los objetos de la familia a través de la definición

abstracta de la familia (interfaz común); no menciona en absoluto las clases concretas utilizadas, que sólo son conocidas por la factoría

o (+)Es fácil cambiar en tiempo de ejecución la familia concreta utilizada (estilo) o (+)Facilita el uso consistente de objetos de una misma familia (sin mezclas) o (–)Dificulta la adición de nuevos productos a la familia, ya que habría que

modificar la interfaz de las factorías y todas las factorías concretas Patrones de estructura: Decorator (p175)

� Propósito: añadir nuevas responsabilidades a un objeto de modo dinámico; ofrece una alternativa más flexible que la herencia para extender la funcionalidad

� Ejemplos: o Añadir elementos gráficos en un editor de documentos o Añadir efectos sonoros o visuales en un juego o Añadir control remoto al mobiliario de una cocina (?)

32

� Problema: o Es posible añadir responsabilidades mediante la especialización: la subclase

hace todo lo que hace la superclase, y añade los efectos deseados o Pero este diseño resulta inflexible, ya que las responsabilidades se definen de

modo estático, no es posible añadirlas en tiempo de ejecución o Podría producirse incluso una explosión de especializaciones, para intentar

reflejar todas las posibles combinaciones de responsabilidades � Solución:

o Empaquetar el objeto dentro de otro que añade las responsabilidades o El objeto que empaqueta o decorador tiene la misma interfaz que el objeto

componente, de modo que su presencia es transparente al cliente o Los decoradores se pueden empaquetar de modo recursivo, formando una

cadena de decoradores ilimitada hasta llegar al componente concreto o La cadena se puede modificar fácilmente en tiempo de ejución, añadiento o

quitando responsabilidades o Cada operación del decorador se transmite por la cadena hasta llegar al

componente concreto; cada decorador puede añadir responsabilidades antes o después en cada paso

� Consecuencias: o (+)Mayor flexibilidad que la herencia, que es estática o (+)Permite la adición incremental de responsabilidades, en lugar de intentar

soportar todas las imaginables en clases complejas o (–)Aunque la interfaz sea la misma, la identidad del decorador no es la misma

que la del componente: transparencia de interfaz, pero no de identidad o (–)Añade multitud de pequeños objetos que sólo se diferencian por la forma en

que están conectados, dificultando la comprensión de la estructura Patrones de comportamiento: Command (p233)

� Propósito: encapsular una petición de servicio dentro de un objeto, de modo que se permita parametrizar las operaciones de otro objeto, mantener colas o registros (logs) de operaciones, y soportar operaciones reversibles

� Ejemplos: o Caja de herramientas para GUI: acciones en respuesta a entradas de usuario o Sistema transaccional: establecer los parámetros de la transacción y ejecutarla o En general, cualquier sistema que distinga dos niveles: operaciones de usuario

de alto nivel, construidas sobre operaciones primitivas de bajo nivel � Problema:

o La caja de herramientas es previa a cualquier aplicación concreta que la use: no puede implementar explícitamente la respuesta a la petición en cada elemento, sino que esta respuesta debe ser parametrizable; sólo la aplicación sabe qué hacer con qué objeto

o Se hace difícil compartir operaciones entre distintos elementos de la interfaz o Flexibilidad: desacoplar la interfaz de usuario de las operaciones subyacentes o Parametrizar la acción deseada mediante herencia conduce a una explosión de

subclases; además, si las acciones son muy distintas y usamos herencia, las subclases resultan muy heterogéneas

o En general, necesidad de ejecutar acciones abstractas, sin conocer en concreto ni el receptor de la operación ni la operación requerida en él

� Solución: o Convertir la petición misma en un objeto y sacarla del objeto invocador o Command declara una interfaz para ejecutar operaciones: execute()

� Ejemplos: PasteCommand, OpenCommand, MacroCommand

33

o Las subclases concretas de Command especifican los pares receptor-acción o El invocador no sabe qué subclase de comando utiliza, por tanto desconoce el

receptor final y la petición enviada: sólo sabe ejecutar el comando o El cliente enlaza invocador con comando, y éste con receptor o Comandos reversibles: añadir unexecute(), state, history list… o Comandos registrados: añadir store(), load()

� Consecuencias: o (+)Desacopla el objeto que invoca la operación del que sabe cómo realizarla o (+)Los comandos son objetos manipulables y extensibles como cualquier otro o (+)Es posible combinar comandos en un comando compuesto: patrón

Composite o (+)Es fácil añadir nuevos comandos sin cambiar las clases existentes

Cómo seleccionar un patrón de diseño (p28)

� Considerar cómo los patrones de diseño resuelven problemas de diseño � Explorar los “propósitos” (intent) de los patrones � Estudiar cómo se interrelacionan los patrones � Estudiar patrones de propósito similar � Examinar posibles causas de rediseño � Considerar lo que podría variar en el diseño

Cómo usar un patrón de diseño (p29)

� Leer el patrón entero para tener una impresión general sin profundizar � Volver a estudiar la Estructura, Participantes y Colaboraciones � Observar la Muestra de Código para ver un ejemplo concreto del patrón � Elegir nombres para los participantes en el patrón que sean significativos en el

contexto de la aplicación � Definir las clases � Definir nombres específicos de la aplicación para las operaciones del patrón � Implementar las operaciones para llevar a cabo las responsabilidades y colaboraciones

en el patrón