Entradas etiquetadas como análisis de requisitos

Líneas Base

Una línea base es el compromiso, negociado y aceptado, que se alcanza con el cliente para que este comprenda que hemos de poner un alto en la captación de necesidades con miras a enfocarnos por unos días, en construir aquello nos ha pedido hasta el día de hoy.

Como estrategia de organización del proyecto, su principal virtud es la de permitir la gestión de requerimientos, al introducir pausas regulares en las exigencias del cliente, con miras a ver primero el logro de las primeras ideas, antes de introducir nuevas variaciones.

Al contar con las líneas base como estrategia de gestión de requisitos, es posible disminuir el riesgo que representan para los proyectos las especificaciones incompletas: simplemente no vamos a aspirar a tener todas las cartas en la mano, vamos a trabajar con lo que tenemos hasta un punto y luego, alcanzados los primeros objetivos, volver a recoger lo que se nos haya escapado la primera vez.

Por lo mismo, es posible también reducir el riesgo de desorden en los requisitos del proyecto. Hay una disciplina en el equipo del trabajo, que se le puede explicar al cliente. Dicho de otra forma, es una forma educada de pedirle paciencia.

, , , , , , , ,

Deja un comentario

Definimos Terminos de Referencia como…

De tanto en tanto nos vamos a encontrar con que la organización que requiere el desarrollo elabora para nosotros un documento de requisitos, en formato libre, al que llaman no sin cierto orgullo “Términos de Referencia”. La práctica viene de otras áreas de la ingeniería donde una petición simple de parte del cliente puede ser analizada y convertida en un trabajo completo, con un razonable nivel de calidad.

Sin embargo, en Ingeniería del Software los términos de referencia no pueden ser utilizados con buenos resultados. Típicamente son documentos incompletos, que mezclan requisitos con análisis e incluso con diseño, cuya existencia es señal de acceso limitado a los stakeholders por parte de la organización de desarrollo. En otras palabras: si nos dan Términos de Referencia tendremos problemas más adelante.

El acto de especificar un sistema de software a demostrado repetidamente ser difícil. Es necesario indicar un gran número de aspectos distintos, mantener la diferencia entre requisito y solución, actuar primero a lo ancho, capturar valor de negocio, entre otros puntos que son propios de nuestra profesión y que resultan incompatibles con las premisas detrás de un documento de términos de referencia.

Veamos algunos de estos puntos en detalle. Comencemos por la definición:

Términos de Referencia: Documento elaborado por el cliente con indicaciones de las especificaciones requeridas al sistema de software por desarrollar.

En otras palabras: en un documento de Términos de Referencia el cliente ha querido ahorrarnos a nosotros el trabajo de especificación. Muy amable de su parte, pero si la organización de desarrollo no interviene en la especificación entonces nos enfrentamos a varios problemas:

  • Se ha asumido un modelo de ciclo de vida en cascada. Los modelos actuales son iterativos, repitiendo múltiples veces el paso de especificación. Un esquema más rígido, como el cascada, suele incrementar el riesgo de fracaso del proyecto.
  • Si el cliente siente que ya ha desarrollado los requisitos a satisfacción puede verse renuente a dedicar esfuerzos nuevos en este asunto. Tendríamos entonces problemas al presupuestar horas para actividades de elicitación de requisitos.
  • El documento en si mismo es un problema. Su estructura es necesariamente ad-hoc, independiente de la metodología que se vaya a seguir en el desarrollo. Puede ser difícil de analizar y haber dejado puntos importantes por fuera.

Si solo fuera para tener una idea del proyecto, básicamente cualquier documento o carta es bueno. Sin embargo los términos de referencia vienen con intenciones más amplias: sustituir la especificación profesional por un único documento, valido para el desarrollo así como para el cálculo de la oferta económica. No importa como lo vea, los términos de referencia son un problema.

Sin embargo, los Términos de Referencia son también un hecho. En algunas situaciones incluso son lógicos: en las licitaciones se distribuyen especificaciones para acto seguido requerir ofertas de costo cerrado. Si esto funciona bien en tantos sectores distintos, el cliente puede pensar que ha de valer también para sus proyectos de software.

Por lo anterior será inevitable que nos topemos con estos documentos. Tendremos que desarrollar entonces alguna técnica para sacar el mayor provecho de los mismos, sin importar cuan diferentes sean de caso en caso y de cliente en cliente. A fin de cuentas ellos son el cliente, y uno no puede ser tan descortez de desachar los resultados de su trabajo.

Finalmente me gustaría recordar que todos sin excepción hemos luchado con los términos de referencia de nuestros profesores y preparadores. ¿Cuantas veces en nuestros estudios tuvimos que llevar a cabo un proyecto a partir de un breve enunciado carente de toda norma de calidad? Así como entonces fue difícil producir un programa autenticamente útil a partir de dichas especifiones, aquí nos va a costar mucho trabajo en conseguir satisfacer el cliente si nos atenemos unicamente a lo dicho en los malvados, digo, en los variables Términos de Referencia.

, , , , , , , ,

3 comentarios

Todo requisito debe ser preciso y legible

La especificación de un sistema es un trabajo retador. En él participan no solo los desarrolladores de aplicaciones, sino también los clientes. Esto significa que la especificación de requisitos, ya sea como casos de uso o como declaraciones tradicionales tipo “el sistema debe…” ha de ser entendida a la vez, por lo clientes y por los desarrolladores. Dicho en otras palabras: la especificación contiene detalles técnicos que los clientes luchan por entender, a la vez que incluye información sobre el negocio que es nueva y potencialmente confusa para los desarrolladores.

Esta situación nos obliga a luchar por dos atributos básicos en todo nuestro sistema de requisitos: la claridad y la precisión.

Precisión de un requisito. Un requisito es preciso cuando indica sin ambigüedad lo que se desea especificar. Debe ir directo al punto y evitar todo adorno en el lenguaje. Debe documentar solo un aspecto del sistema y lo debe de hacer en forma exacta.

Y también

Claridad o legibilidad de un requisito. Un requisito es legible cuando el lenguaje en el que esta escrito es fácil de entender, tanto por los clientes como los analistas. La legibilidad se extiende no solo a la especificación escrita, sino también a los formalismos gráficos como los diagramas de casos de uso.

Es curioso observar que en los cursos universitarios sobre el tema, los profesores tengan la presión de explicar métodos y técnicas avanzadas, como las relaciones de extensión e inclusión de casos de uso, forzando al estudiante a adoptar estar técnicas en forma demasiado temprana. Esto causa una deformación profesional en el estudiante, quien sale del curso con la creencia que es mejor una especificación sofisticada que haga uso de todo lo visto en el curso, en lugar de una aproximación más informal y relajada que puede en verdad ser entendida por el cliente.

El lugar correcto para la extensión y la inclusión, así como para todas las técnicas de modelado de requisitos más sofisticadas, es en aquellos dominios de aplicación donde los requisitos reales sean muy complejos. Es decir por lo tanto, que en la práctica el analista ha de hacer esfuerzos por mantenerse sencillo, normalmente no vale la pena la complejidad del modelo de requisitos.

También es de hacer notar, que en mi experiencia la mayoría de los clientes intentan hacer otro tanto. Ellos suelen expresar lo que necesitan en la forma más directa que tienen disponible, sin embargo dado que los clientes son a su vez profesionales en un área especifica, la forma correcta en la ellos se expresan suponen tensión a los desarrolladores, quienes deben luchar por desarrollar un vocabulario común con el cliente para poder comprender sin errores lo que este pide.

En conclusión: lo sencillo se entiende más y la especificación de un sistema ha de entenderse bien. Cuan sofisticado hagamos nuestro modelo de casos de uso o nuestro documento de especificación, no es ni de lejos lo que en verdad importa. Es mucho mejor un caso de uso sencillo pero que captura valor de negocio, que uno sofisticado que haga un uso abundante de las técnicas más esotericas de modelado.

, , , , , , , , , , ,

2 comentarios

Un buen requisito debe ser atómico

“Un buen requisito debe ser atómico” lo digo y lo repito: Un buen requisito debe ser atómico. Sin embargo esto no significa que debe guardar alguna relación con la industria militar o la energía atómica. Si bien el átomo es un concepto de la ciencia moderna, el adjetivo atómico significa indivisible o dicho en otras palabras: único, singular, no susceptible a ser dividido.

Claro que eventualmente lo vamos a analizar y de ahí, que propongamos una relación de objetos que al colaborar den a lugar la funcionalidad requerida; pero el requisito en si mismo ha de describir un único requisito.

Y es que ocurre que en ocasiones un analista despistado, construye un cuerpo de requisitos donde uno o más de estos, contiene alguna forma de declaración compuesta, de forma que se refiere sin querer, a más de una característica.

La misma necesidad de atomicidad es requerida en los casos de uso. Un buen caso de uso debe hablarnos de un escenario de interacción completo y singular de manera que pueda ser tomado como una unidad indivisible.

Varios trucos se pueden dar para lograr este criterio de atomicidad: evitar las declaraciones compuestas y referirse en todo momento a una única característica son solo las dos primeras que me vienen a la mente. Sin embargo, como las recetas universales siempre tienen casos en que fallan, me limitaré a solo indicar lo que queremos: un requisito de buena calidad siempre ha de ser atómico.

El como lo logre el analista de requisitos es más cosa de habilidad que de consejos leídos por ahí.

, , , , , , , , , ,

5 comentarios

Ejemplo de análisis de caso de uso

Si el análisis pone en descubierto las partes de aquello que se ha visto como un todo, entonces el análisis de casos de uso ha de poner en descubierto las instancias que intervienen en el sistema a la hora de realizar la funcionalidad descrita en dicho caso de uso.

Para efectos de la tarea análisis de caso de uso, en su versión con modelo de domino, dichas instancias van a pertenecer a alguna de las clases descritas en el modelo de dominio. El objetivo del análisis va a establecer los detalles de la relación que es necesaria que tengan estas clases para lograr la funcionalidad descrita en el caso de uso.

Tomemos el siguiente modelo de dominio para el sistema de subterráneo (Metro) de una ciudad cualquiera:

Fig. 1 – Diagrama de clases del modelo de dominio del sistema metro

Y complementemos con el siguiente modelo de casos de uso; asumiendo de momento que los casos de uso han sido descrito en detalle en algún documento apropiado.

Fig. 2 – Diagrama de casos de uso del sistema metro

Finalmente, tomemos el caso de uso Compra de Ticket para completar nuestro ejemplo:

Nombre: Compra de Ticket.
ID: N/A.
Actor: Usuario del Metro.
Descripción breve: El usuario del metro compra un boleto del sistema luego del pago de la cantidad apropiada.

Tabla 1 – Detalles del caso de uso: Compra de Ticket

Ya armados con todos estos detalles, nos podemos hacer la siguiente pregunta:

¿Qué clases del modelo de dominio intervienen en el caso de uso?

No existe una respuesta necesariamente correcta, queda a juicio del analista el tomar una u otra clase según su visión y particular enfoque del problema; en mi caso, he tomado las clases Usuario del Metro, Venta de Ticket, y Ticket.

Luego de identificar que conceptos de nuestro modelo de dominio intervienen en el caso de uso, necesario ahora indicar cuales son los mensajes que estas instancias deben intercambiar para completar la funcionalidad. Este intercambio lo presentamos en un diagrama de UML, típicamente un diagrama de secuencia.

Fig. 3 – Diagrama de secuencia con el escenario de análisis
del caso de uso: Compra de Ticket

El resultado de nuestro análisis ha sido una primera versión de los mensajes que han de intercambiar las instancias de las clases Usuario del Metro, Venta de Ticket y Ticket, para lograr la funcionalidad requerida en el caso de uso Compra de Ticket.

Hay que fijarse que el modelo de domino original tenía pocos o ningún atributo o método para sus clases. El resultado del análisis es que ahora estas clases han sido detalladas un poco más, indicando para algunas de ellas (las que intervienen en el los escenarios de análisis) cuales métodos son necesarios e incluso, el proposito de cada uno de estos.

Cuando se parte de un modelo de dominio, el análisis de caso de uso no hace más que enriquecer este modelo, detallando como he dicho ya, cuales métodos son necesarios que estén presentes. Al final, el análisis habrá completado un esbozo de un modelo del sistema; modelo este que ya habrá asumido todos los requisitos de nuestros clientes y presentará una relación de clases capaz de instanciar lo visto en el análisis.

Queda por supuesto más pasos antes de contar con un sistema listo para su uso; es necesario que realicemos la integración con las clases de análisis (si las hemos usado) así como llevar a cabo el diseño del sistema; es decir, aún no estamos listos para programar, pero si estamos listos para diseñar.

, , , , , , , ,

12 comentarios

Casos de Uso Avanzados: Relación de Inclusión

El modelado de casos de uso persigue capturar la funcionalidad del sistema visto desde el punto de vista de sus operadores -actores- por lo que es fundamentalmente una construcción de elementos de modelado comprensibles por los clientes -stakeholders- y no solo por los analistas.

Sin embargo, en ocasiones es conveniente introducir algunos pocos elementos que no sean directamente los conceptos que manejan los clientes. Por ejemplo, en aras de evitar la redundancia, es posible pensar en extraer algunos fragmentos que nos permita indicar en uno o más casos de uso este fragmento repetido, por referencia en lugar de repetirlo en cada caso.

A este proceso de extracción del fragmento repetido lo modelamos por medio de la relación de inclusión <<include>>, tal como se ve en el siguiente diagrama:

Fig. 1 - Relación de inclusión entre casos de uso

En la figura, el caso de uso “A” es un fragmento, que define un trozo de un flujo de eventos que es referido por el caso de uso “B”. En este tipo de relación, el caso incluido (el “A”) debe ser un fragmento, nunca un caso concreto, en tanto que el caso que incluye (el “B” del ejemplo) si ha de ser un caso de uso completo.

A diferencia de la relación de extensión, aquí ninguno de los casos de uso involucrados puede ser entendidos por completo como piezas aisladas. Por un lado, el caso incluido es solo un fragmento, por lo que no es posible considerarlo un caso de uso pleno; en tanto que el caso que incluye al hacer referencia a un fragmento externo tiene necesariamente que ser entendido en presencia del fragmento.

Formalmente, como para el glosario:

Relación de Inclusión <<include>> Un caso de uso concreto incluye a un fragmento de caso de uso, cuando como parte de su descripción breve o su flujo de eventos, se hace referencia al texto del fragmento; de forma tal que lo dicho en el fragmento pasa a ser parte de la especificación del caso de uso.

Para lograr que se entienda el concepto, nada mejor que un ejemplo. Supongamos que estamos hablando de un sistema de gestión de agenda de un empresas con gerentes y asistentes. En este sistema hemos identificado dos casos de uso:

Código: UC-0100.
Nombre: Acepta cita.
Actor: Gerente.
Descripción: El Gerente visualiza su calendario de citas y aprueba aquellas citas que desee aceptar.

Código: UC-0200.
Nombre: Coordina cita.
Actor: Asistente.
Descripción: El asistente busca un momento apropiado para las citas pendientes al visualizar el calendario de citas del Gerente. Indica para cada cita propuesta la descripción, el día y la hora.

Tabla 1 - Casos de uso del sistema

Como se nota, en ambos casos se requiere de visualizar la agenda. Es posible imaginar que esta función abarca no solo la visualización del calendario, sino también ciertas funciones de búsqueda y filtrado por criterios. Para especificar esta funcionalidad pero evitar hacerlo en cada uno de los flujos de eventos de los casos de uso ya definidos, se opta por crear un fragmento que contenta esos detalles e incluirlo en los casos de uso originales. La situación da lugar al siguiente diagrama:

Fig. 2 - Modelo de casos de uso con un
ejemplo de relación de inclusión

De esta forma, evitamos tener que definir en múltiples lugares una misma funcionalidad. Sin embargo, el fragmento que se incluye ha de ser visto siempre como lo que es: un fragmento sin significado completo. En verdad es una lastima que de momento no tengamos una forma de marcar a los fragmentos de manera que se diferencien a simple vista de los casos de uso. Sugiero que al menos, en tanto surge un estereotipo estándar para esta tarea, tengamos una serie de numeración particular para los fragmentos. O bien, tomar la iniciativa y definir un estereotipo de UML por nosotros mismos.

Naturalmente que a la hora de hacer la especificación detallada de los casos de uso, en particular en los flujos de eventos, debemos marcar muy claramente en que lugar se ha de realizar la inclusión de lo dicho en el fragmento.

La relación de inclusión es claramente diferente a la relación de extensión y espero que haya quedado claro. La inclusión es una relación entre un caso de uso concreto y un fragmento, en tanto que la extensión involucra casos de uso concretos.

Por otra parte, a diferencia de la relación de extensión, la inclusión en cierta forma modifica al caso que incluye, por cuanto el fragmento define una parte de la funcionalidad del caso de uso completo. Esto significa que el caso de uso que incluye no puede ser entendido por completo en ausencia del fragmento que se incluye; algo muy diferente a la situación en una relación de extensión.

, , , , , , , , , , , , ,

29 comentarios

Casos de Uso Avanzados: Relación de Extensión

En muchas ocasiones el uso de características avanzadas de los casos de uso generan dudas en los equipos de desarrollo. La razón básica es que estos modelos deben ser claros antes que cualquier otra cosa, lo que lleva a evitar el uso de las relaciones de inclusión y extensión, entre otras características.

Sin embargo, por muy de acuerdo que podamos estar con el deseo de claridad y sencillez, existen situaciones en que hacer uso de una relación avanzada entre casos de uso mejora en lugar de reducir, la claridad del modelo de requisitos. De ahí por tanto que todo analista de requisitos debe comprender perfectamente el significado de estas relaciones. En el presente post abordamos la relación de extensión <<extend>>.

Técnicamente como para el glosario, la relación de extensión <<extend>> se define como:

Relación <<extend>> Un caso de uso extiende a otro cuando sin alterar a este, se incorpora su funcionalidad como parte integral del primero. Se denota con una relación que apunta del caso extendido al caso base y la conexión se hace o bien al principio del flujo de eventos principal del caso base o en alguno de los puntos de extensión que este haya definido.

La notación gráfica es la siguiente:

Fig. 1 - Relación de extensión <<extend>>

La relación del ejemplo significa que un caso de uso ya existente (el caso “A”) se aprovecha en la definición de un segundo caso (el caso “B”). Dado que la reutilización que requerimos agrega funcionalidad pero no altera al caso base, se ha optado por la relación de extensión. Dicha relación se ha denotado gráficamente con una flecha de dependencia desde el caso extendido (el caso “B”) al caso base (el caso “A”). La dependencia la hemos estereotipado con <<extend>> para que quede claro lo que pretendemos decir.

A nivel de los flujos de eventos, se podría decir que el flujo principal del caso base no se ve alterado, pero que en cambio, el flujo de eventos del caso extendido hace referencia al primero, de manera tal que no puede ser entendido en ausencia de los pasos del caso base.

A fin de contar con un ejemplo completo, consideremos un sistema de compras electrónico. Digamos que este sistema va a atender tanto a clientes finales como a clientes corporativos, permitiendo que adquieran productos en nuestra tienda en línea. La diferencia será que los clientes corporativos hacen compras masivas, quizás programando la entrega a lo largo de un periodo de tiempo de lo que compraron. Esta visión la podemos expresar en el siguiente diagrama:

Fig. 2 – Ejemplo de relación <<extend>> en un sistema
de tienda electrónica en Internet

Ahora si vamos al caso de uso base “Compra artículo (UC-0100)” podríamos tener la funcionalidad de escoger el artículo a comprar y el de pagar con tarjeta de crédito, por ejemplo. Esta funcionalidad esta disponible a los clientes finales, tal como se ve en el diagrama.

Por su parte, los clientes corporativos pueden escoger el artículo a comprar y el modo de pago: digamos tarjetas de crédito. Además el caso de uso captura también la funcionalidad de programar la entrega parcial de lo comprado a lo largo de un periodo de tiempo. Dado que gran parte del caso de uso “Compra masiva (UC-0200)” es idéntica a la encontrada en el caso del cliente final, optamos por reutilizar la especificación por vía de la relación de extensión.

Los criterios a aplicar para saber si la relación de extensión es aplicable son los siguientes:

  1. Hay cuando menos un caso base y un caso extendido.
  2. El caso base no se ve modificado por la existencia del caso extendido.
  3. El caso base es un caso concreto atado a cuando menos un actor.
  4. El caso extendido incorpora al caso base por completo.

La relación de extensión guarda relación con todos los restantes tipos de reutilización que están definidas para los casos de uso; en particular la relación es muy intima con la relación de inclusión <<include>> sin embargo la diferencia primordial entre <<extend>> e <<include>> es la modificación del caso base. Extensión no implica cambio, en tanto que la inclusión añade funcionalidad al caso base.

Otra relación, la herencia, es similar también a la extensión. En este caso la diferencia es que la herencia cambia o puede cambiar, la naturaleza de lo dicho en el caso base. Por ejemplo, podemos decir que aquello que fue llamado “artículo” en el caso base es ahora referido más detalladamente como “libro” o “juguete”. La herencia de casos de uso reutiliza al caso base sí, pero nos permite alterar la semántica de los detalles; algo que la relación de extensión (ni la de inclusión) pueden hacer.

Por tanto concluyamos: la relación de extensión permite reutilizar una especificación pero sin modificar al caso base.

, , , , , , , , , , , , ,

32 comentarios

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 25 seguidores