Patrones de Casos de Uso 2/9 – Object Manager

En el artículo anterior hemos visto una introducción a los patrones de contenido de casos de uso presentados por Martin Langlands. Ya vimos brevemente explicados los patrones, por lo tanto a partir de este artículo, comenzaremos a verlos uno por uno, haciendo también algunas traducciones del paper original para mantener la idea de Langlands y dando mi opinión al respecto. Los patrones no serán explicados en el mismo orden que Langlands los presenta en su paper, sino que iré escribiendo los artículos desde otra perspectiva.

El primer patrón que me gustaría tratar es el OBJECT MANAGER. Este patrón, de alguna manera, agrupa a los demás patrones presentados por Langlands, y hay que recordar que estos patrones de casos de uso tratan sobre el contenido de los casos de uso y no así a cómo estructurarlos (lo que sería el concepto descrito en el paper como “Inside the Oval”). Sin embargo, este es el único patrón que trata más bien sobre como organizar los patrones de contenido presentados.

Por lo general, cuando hablamos de sistemas, hablamos de trabajar con una base de datos o alguna forma de almacenamiento de datos. Durante la etapa de análisis, cada objeto que tiene la capacidad de persistir sus propiedades en una base de datos es conocido como una entidad, y este tipo de objetos son con los que más lidiamos a la hora de la descripción de casos de uso.

De esta manera, hablamos de los CRUDs o ABMs que nos permiten “administrar” o “gestionar” las entidades. Estos dos términos son muy utilizados a la hora de modelar casos de uso, es más, personalmente creo que son los que más retrasan el modelado, no por ser complicados, sino porque no se tiene un criterio uniforme para modelarlos y describirlos. Con este patrón, Langlands comenta que “cada uno de estos tipo de objetos (entidades), necesitan generalmente un conjunto de casos de uso para que los usuarios puedan administrar las instancias a través de su ciclo de vida.”, y hace referencia en que encuentra las siguientes funciones:

  1. Crear nuevas instancias. Patrón: BASIC CREATOR
  2. Buscar instancias, pudiendo utilizar varios criterios para encontrarlas. Patrón: CRITERIA SEARCH
  3. Visualizar los detalles o datos de una instancia específica y opcionalmente modificarla. Patrón: VIEWER/UPDATER
  4. Seleccionar instancias de objetos para utilizarlos en otro contexto, como por ejemplo, seleccionar la ciudad de una persona a la hora de querer crear la persona. Patrón: SELECTOR
  5. Eliminar instancias que ya no son útiles para el sistema. Patrón: DESTRUCTOR

Cada uno de estos conceptos serían los patrones de contenido de los casos de uso que vamos a ir viendo en esta serie de artículos, y a estos se añaden los patrones KNOWN OBJECT y PROPERTY LIST que son más bien conceptos a tener en cuenta a la hora de trabajar con los demás patrones. El patrón KNOWN OBJECT (Objeto conocido) nos dice simplemente que a la hora de trabajar con un objeto específico asumamos que el objeto en cuestión ya lo tenemos y lo conocemos, mientras que el patrón PROPERTY LIST nos explica como podemos detallar las propiedades de un objeto o datos a ser utilizados en un caso de uso, por ejemplo cuando queremos modificar los datos una persona y debemos definir justamente cuáles son esos datos.

En el caso del patrón OBJECT MANAGER, no habla del contenido en sí, sino de como agrupar o modelar las funcionalidades de los casos de uso que se describen arriba y las relaciones entre los demás patrones (includes). Para esto, Langlands hace el siguiente resumen:

  1. Los casos de uso que utilicen los patrones VIEWER/UPDATER, SELECTOR y DESTRUCTOR, deberían ser invocados únicamente desde otros casos de uso del sistema. Esto es así porque estos patrones trabajan de por sí con un objeto específico y conocido, concepto dado por el patrón KNOWN OBJECT. Es decir, cuando queremos ver, modificar o eliminar un objeto tenemos que saber cual.

  2. Un caso de uso que utilice el patrón VIEWER/UPDATER, por un lado puede ser invocado desde otros casos de uso del sistema, como se menciona arriba, por ejemplo casos de uso que utilicen los patrones BASIC CREATOR, CRITERIA SEARCH o SELECTOR, y por otro lado puede invocar a un caso de uso DESTRUCTOR.

  3. A diferencia de los patrones explicados arriba que deben ser invocados por otros casos de uso que actúen como clientes, el BASIC CREATOR y el CRITERIA SEARCH pueden ser invocados directamente por un actor ya que estos patrones no necesitan el concepto del patrón KNOWN OBJECT como precondición.

  4. Los casos de uso que utilicen el patrón BASIC CREATOR pueden ser invocados también desde otros casos de uso que utilicen los patrones CRITERIA SEARCH y SELECTOR.

Por supuesto, a parte de estas funcionalidades, existirán muchas otras y no necesariamente esto deba ser como se indica en el resumen anterior, sino que se debe tomar como una base o framework para realizar el análisis de los casos de uso. Por ejemplo, dependiendo del caso se podría querer:

  • Crear objetos (BASIC CREATOR) solo por medio del menú. En este caso el inicio del caso de uso es realizado solo por el actor como se explica en el punto 3 del resumen y no permitiría la posibilidad de crear los objetos por medio de la búsqueda (CRITERIA SEARCH) como habla el punto 4.

  • También podría, desde la búsqueda (CRITERIA SEARCH) ejecutar otras acciones como cambios de estado sobre los resultados, por ejemplo activar o inactivar las instancias encontradas. Esto lo veremos en el artículo sobre este patrón.

Esto podríamos representarlo con el siguiente diagrama de casos de uso:

Use-Case Content Pattern: Object Manager – Inside The Oval, page 49

Cada uno de estos casos de uso ilustrados en el diagrama de casos de uso de arriba, tienen sus propias reglas, o mejor dicho aún, sugerencias dada por Langlands y cada una de ellas las veremos en los siguientes artículos.

Opinión personal – (actualizado el 10 de diciembre del 2013)

Herramienta de Análisis

Esta forma de modelar casos de uso la tenía en mi cabeza desde hace mucho, pero más bien pensados como un flujo de trabajo. Me parece muy interesante la explicación y aplicación de Langlands sobre este tema, dejando una base que, en mi opinión, debe ser un trabajo del analista y no del desarrollador.

Supongamos que el diagrama de casos de uso que se muestra arriba está orientado al objeto Persona. Como analistas, estamos marcando y documentando una funcionalidad que debería de ser respetada por el desarrollador. Para crear una nueva Persona, vemos una asociación directa que proviene del actor. Por más que no estamos especificando diseño, estamos diciendo que tiene que haber una forma en la que el actor pueda crear directamente una Persona, y esto podría ser interpretado como por ejemplo una opción en el menú (hay varias formas de interpretarlo en diseño). Sin embargo también decimos que debería crearse una Persona con una acción desde la búsqueda (SEARCH CRITERIA). Muy importante es entender que tampoco expresamos el cómo, sino que como analistas decimos que debe haber una opción (link, botón o cualquier otra forma que será definida en la etapa de diseño). En el caso de que en la etapa de análisis, entendamos que no conviene realizar la acción desde la búsqueda, no se modelaría el << include >>, y esto debería de ser entendido y aplicado por los diseñadores y programadores.

Esta forma de expresar y documentar los casos de uso, provee una herramienta muy útil al analista para poder marcar un estándar en el sistema, y por medio de un diagrama de casos de uso, visualizar a alto nivel como las principales funcionalidades se van ejecutando y desde donde lo hacen.

Esto suele ser útil cuando hablamos de ejecutar acciones desde un buscador (veremos la forma de hacer esto cuando hablemos sobre le patrón SEARCH CRITERIA). En algunos sistemas se suele pedir que cuando se encuentren resultados en la búsqueda, dependiendo de los estados de los registros, se agreguen acciones que invocarían a otros casos de uso (esto se ve en el diagrama de casos de uso de arriba con el << include >> que va hacía OTHER USE-CASES), mientras que en otros sistemas se da acceso solo a una visualización y las acciones son invocadas desde ahí. Yo considero que lo mejor es ingresar a la visualización primero, ya que si son muchas acciones en el buscador, el sistema deberá realizar varias validaciones para mostrar o no las acciones por cada uno de los resultados de la búsqueda, lo que podría dar problemas de performance al sistema, mientras que si visualizamos el registro primero, por más que se ejecutarían la mismas validaciones para mostrar o no las acciones, esto se realiza una sola vez por cada una ya que en este momento hablamos de solo un registro y no varios.

Ahora bien, ¿por qué hablo de performance del sistema cuando escribo casos de uso, siendo que estos temas deberían de ser abordados en la etapa de diseño del sistema y no en la etapa de análisis? Es una opinión muy personal, pero considero que temas que pueden ser estandarizados pensando como analistas, sabiendo que podrían ayudar al performance sin importar de qué tecnología usemos, sino más bien por las funcionalidades del sistema que estamos definiendo, deben ser tratados en la etapa de análisis en los casos en los que la experiencia misma ya nos alerta sobre este tipo de puntos. Diciéndolo de otra manera, el problema de performance no es porque usemos JAVA o PHP o un framework u otro, sino más bien porque la misma lógica que el sistema deberá usar para mostrar las acciones tendrán un efecto sobre la rapidez de la respuesta, sin importar la tecnología. Por lo tanto quizás se pueda analizar con los usuarios, cuáles acciones dejamos en los resultados de las búsquedas para accesos más rápidos, y cuáles se podrían llevar a un programa que visualice primero el registro y desde ahí ejecutar las acciones. Esto podría ser modelado perfectamente en el diagrama de casos de uso con los << includes >> y los diseñadores y desarrolladores lo pueden prever.

Otros patrones que podría incluir

El patrón VIEWER/UPDATER incluye ambas operaciones, la de visualizar y la modificar. Ciertamente la modificación la deja como opcional, y entraremos en más detalles en el contenido cuando veamos el artículo sobre este patrón, pero viéndolo desde el punto de vista de patrón OBJECT MANAGER quizás se podría separar ambos patrones en dos por los siguientes motivos:

  1. Unificando estas dos funcionalidades dentro de un solo caso de uso, podría hacer pensar al desarrollador que debería hacer las dos cosas en la misma pantalla o programa. Podemos dejarle pensar que al ser la misma pantalla, puede utilizar la misma para ver y modificar datos, tomando en cuenta que para modificar los datos los puedo ver. Al dejar de lado la pantalla de solo lectura de los datos de una entidad, olvidamos por completo a usuarios con perfiles como por ejemplo Auditoría que no debe poder realizar ninguna modificación.

  2. Por otro lado, el desarrollador podría pensar que en la misma pantalla puede usar INPUTs para modificar los datos y dejarlos como deshabilitados cuando solo indique la visualización o cuando los permisos del usuario así lo requieran, pero este es un error que conlleva a un problema de seguridad grave, ya que con herramientas como Firebug podríamos habilitar estos INPUTs permitiendo la modificación en caso de estar utilizando programación Web.

Estos puntos mencionados corren la misma suerte que la explicación usada arriba, ¿No serán estos temas de diseño y no de análisis?. Bueno, considero nuevamente que son funcionalidades del sistema y no pantallas, por lo tanto yo prefiero dejar esto en la cancha de los analistas quiénes se suponen conocen más sobre el negocio que los desarrolladores, y estos últimos se deberían enfocar más bien en aspectos de implementación y diseño de las pantallas (selección de componentes a usar de acuerdo a la tecnología).

La separación de este patrón en dos permitiría asegurar al analista que el desarrollador entienda que son dos funcionalidades diferentes. Quizás se podría hacer una pequeña modificación quedando como sigue:

Use-Case Content Pattern – Object Manager – Propuesta

Los cambios realizados serían:

  1. Se separa el patrón Viewer/Updater en dos: Viewer y Updater

  2. Desde la visualización podríamos ir a la actualización y los demás includes van directamente al Viewer. El updater podría ser incluído también desde la búsqueda si se quiere.

  3. Las acciones que se ejecutan desde la búsqueda (OTHER USE-CASES) también podrían ser llamadas desde el Viewer tomando en cuenta el punto descrito anteriormente (Herramienta de Análisis).

Si hiciéramos estos cambios quizás podríamos estar hablando de una modificación en el patrón OBJECT MANAGER quedando algo parecido al diagrama anterior, donde podemos notar que la actualización de datos de un objeto (UPDATER) debería venir por la visualización (VIEWER), centralizando y obligando a denotar que debe tomarse en cuenta programas diferentes.

Dejo abierta la discusión sobre esta idea y espero sus comentarios.

Inconvenientes con el patrón OBJECT MANAGER

Un pequeño inconveniente que puedo notar en este patrón es que por la utilización de los includes, las asociaciones van directas desde el actor solo para los patrones SEARCH CRITERIA y BASIC CREATOR, por lo que desde el diagrama de Casos de Uso es difícil notar cuáles son los actores que interactúan directamente con cada Caso de Uso.

Supongamos el caso de cambios de estados sobre un registro (representados por OTHER USE-CASES), en donde algunos cambios de estado vienen dados por el Actor1 y otro por el Actor2. En el diagrama de casos de uso lo más probable es que las asociaciones con estos actores sea con el SEARCH CRITERIA, y no sería posible notar directamente cuales Casos de Uso, que representan cada cambio de estado, son invocados por uno u otro actor.

De todas maneras, dentro de la descripción de cada Caso de Uso, se debe indicar los actores que interactúan realmente, por lo que considero que este inconveniente podría ser mínimo comparado con las herramientas que me provee para el análisis, de todas maneras lo quiero dejar por sentado para abrir el debate.

Comunicación con Martin Langlands

En estas semanas tuve la suerte de ponerme en contacto con Martin Langlands. Le comenté algunas dudas y entre una de las respuestas me pareció muy interesante una en particular.

Le consulté si las flechas de los << includes >> que salen del SELECTOR y van hacia el BASIC CREATOR y el VIEWER/UPDATER no deberían de ser en la dirección contraria, ya que desde la creación o incluso desde la modificación se suele utilizar un SELECTOR para obtener datos de objetos relacionados. Su respuesta fue muy acertada cuando me comentó que el patrón OBJECT MANAGER está orientado a un objeto en particular, es decir que se mira el diagrama de casos de uso de este patrón pensando en por ejemplo el objeto Persona. En el caso de crear una Persona (BASIC CREATOR), no estaríamos accediendo al patrón SELECTOR para consultar nuevamente una persona, a menos que se trate de una relación recursiva por supuesto, sino que desde la creación de esa persona accederíamos por ejemplo a un selector de países. El País ya es otro objeto por lo que esto es representado por el include que va desde “OTHER CLIENTE USE-CASES” al SELECTOR. Ahora bien, las flechas están así porque desde un SELECTOR, como veremos en el artículo sobre este patrón más adelante, se pueden crear objetos de este tipo o incluso visualizarlos para tener certeza de que estamos eligiéndolo bien. Por este motivo dejo por sentado que las flechas de los << includes >> están correctas.

Otros artículos relacionados

Simplificando los Modelos de Casos de Uso usando el Patrón CRUD

Existe un artículo escrito por Prashant y Sarika Gupta, y publicado por el International Journal of Soft Computing and Engineering (IJSCE) titulado “Simplifying Use Case Models Using CRUD Patterns”.

Este artículo trata sobre los casos de uso para CRUDs, es decir para administrar objetos pequeños que no valen la pena tener varios casos de uso, a diferencia de patrón OBJECT MANAGER que estamos viendo en este artículo. Este concepto serviría perfectamente para tablas paramétricas que generalmente son pequeñas y que sirven para utilizar los datos como referencias dentro de otras tablas. Ahora bien estas tablas podrían ser candidatas a ser utilizadas por medio de un caso de uso con el patrón SELECTOR.

Este patrón CRUD puede ser usado para no dejar de documentar los casos de uso para la administración de estas tablas con lo cual los usuarios podrían pasar por alto cierta funcionalidad del sistema.

El artículo lo pueden descargar de aquí.

Casos a incluir y Casos a extender

También existen otras opiniones con respecto a la utilización de los << includes >>, en cuanto a ir uniendo los casos de uso y tratar de comunicar al usuario el orden en que ocurren, o en el que debe ejecutarse los casos de uso. Estoy muy de acuerdo con lo comentado por los autores “Debe de existir una razón importante para que decidamos dividir un caso de uso en dos que serán unidos por medio de alguna de estas relaciones”, y considero que la utilización de estos patrones mencionados en esta serie de artículos es una de ellas, considerando también que existe un patrón CRUD que menciono arriba.

Les dejo el artículo publicado por Sergio Orozco y Leticia Ortiz titulado Casos a incluir y Casos a excluir para que cada uno pueda también tomar sus conclusiones.

Referencias

Langlands, M. (2013). Inside The Oval : Use-Case Content Patterns (version 2.0), páginas 48 y 50.

Prashant, Sarika Gupta (2012, Mayo). Simplifying Use Case Models Using CRUD Patterns. International Journal of Soft Computing and Engineering (IJSCE).

Orozco S., Ortiz L. Casos a incluír y casos a extender

Comenta este artículo