Buscar en este blog....

Mostrando entradas con la etiqueta UML. Mostrar todas las entradas
Mostrando entradas con la etiqueta UML. Mostrar todas las entradas

sábado, 4 de septiembre de 2010

Ejemplo de uso del patron Observer

Ahora que hice el último patrón que se nos había encomendado implementar, el patrón Observador, voy a poner el ejemplo como hice con el patrón Command.

La idea es la siguiente: tenemos un caso de uso "Marcar Gol" que se dispara -imaginemos- cuando un sensor ubicado en un arco de fútbol detecta que pasa la pelota. Al dispararse este caso de uso, se llama al método de su experto anotarGol(), quien -entre otras cosas- llama al método actualizar() de SuscriptorGoles.

La interfaz del caso de uso "Ver Resultados" llama al método inciar() del controlador, con el cual éste se suscribe a SuscriptorGoles para que SuscriptorGoles llame al método actualizar() del controlador. Este método, lo implementa de la interfaz IObservadorGoles.

Notemos que SuscriptorGoles tiene un arreglo (o lista) de IObservadorGoles para actualizar a cada observador suscrtipto a el.

En el diagrama de clases olvidé especificarlo, pero conviene que SuscriptorGoles sea un singleton, ya que no vamos a usar más que una sola instancia de él.

Implementación en C#: Descargar

Salutes!

sábado, 28 de agosto de 2010

Ejemplo de uso del patron Command

Buenas, gente. Decidi subir este ejemplo al blog porque tuve que hacerlo para la facultad y por ahi viene bien ver algunos ejemplos, aunque que abunden en internet.
Como dije, se trata de un ejemplo aplicado del patrón Command a un negocio que tiene que ver con una escuela.

La idea es que cuando en dicha escuela se programan las fechas de exámenes, se debe notificar a los profesores, a los padres de los alumnos, a la Dirección General de Escuelas, y debe además, mostrarse en la cartelera. Es un caso ficticio, inventado para el ejemplo. La idea es que a los profesores se les debe enviar una notificación impresa a la casa, a los padres se les avisa por e-mail, a la DGE se le puede avisr por e-mail o por notificacion escrita (da igual). Digo que da igual, porque no me he centrado en el proceso particular de cada notificación en sí, sino solo en la aplicación del patrón Command.

Cuando el experto del caso de uso "Programar Fechas de Examenes" confirma dichas fechas, se debe proceder a hacer las notificaciones para cada caso. Eso es lo que está en el ejemplo.

El lenguaje utilizado es C#, con el IDE Visual C# 2008 Express Edition. Pueden descargar el código fuente y ver el diagrama de clases.

Código Fuente : Descargar
Diagrama de Clases: Descargar o la imagen.

Saludos!

viernes, 29 de mayo de 2009

¿Validar las precondiciones?

La idea de escribir este postsurgió de una charla que esuché ayer entre un compañero de la meteria "Diseño de Sistemas" y la profesora. Él decía que las precondiciones no se debían evaluar dentro del caso de uso -o sea que no debería ser parte del flujo de ese caso de uso el validar que dichas precondiciones se cumplirian- y por el contrario, son condiciones que ya deben haberse cumplido antes de disparar ese caso de uso. La profesora, en el otro extremo le decía que sí debían validarse dentro del caso de uso.

En principio estuve de acuerdo con mi compañero, porque pensé que esa es justamente la definción de "precondición" (de hecho, la misma palabra lo dice).

Además, la definición formal de precondición es: "una operación que debe ser cierta cuando se invoca una operación". En el Manual de Referencia de UML se agrega, despues de esta definición, que el receptor no debe tener que verificar la condición.

Aunque con estos argumentos parece tener la última palabra mi compañero, la profesora tenía algo más que razón. Quizás su punto de vista no encaja exactamente con el del paradigma de orientación a objetos, o mejor dicho, con las definiciones que se proponen en UML. ¿Entonces está mal su punto de vista?

No. Si recordamos los principios básicos de la orientación a objetos, uno de ellos se refería a la capacidad de reutlizar componentes. Componentes que son de un sistema, pero sirven para otro, pueden ser reutilizados para evitar volver a construirlos. Un caso de uso, por ejemplo, puede ser reutilizado si dos sistemas tienen algun requisito en común. Este caso de uso tendrá sus propias precondiciones que el peimer sistema (llamémosle sistema A) se encarga de "poner a punto" antes de llamarlo. Con "poner a punto" me refiero a que el sistema sabe que caso de uso se llamará -previo al caso de uso que vamos compartir- de forma que el sistema queda en un estado tal que el caso de uso que vamos a compartir tiene "verificadas" esas precondiciones.
¿Pero quien me asegura que esto sea realmente asi? o peor aún, ¿quien me asegura que el nuevo sistema (sistema B) también se encargue de llamar al caso de uso compartido con las precondiciones validadas? Nadie.

Entonces, quizás sea esto lo que la profesora quería decir. Si el mismo caso de uso verificara sus precondiciones, entonces no hay problema de reutilizarlo, ya que el mismo se asegura -donde quiera que lo pongan- que las condiciones se validen. De no validarse, sencillamente no se ejecutará. Esto evita que el sistema llegue a estados no válidos, o de resultados incorrectos.

Entonces, ¿para qué están las precondiciones? Bueno, es un dato más sobre la interfaz del caso de uso. Si conozco las precondiciones, no necesito saber que hace un caso de uso -qué valida y que no- sino simplemente usarlo. Es decir, la precondición como tal es un aspecto más bien ligado al análisis y al diseño, mientras que la verificacion de ésta está más ligada a la implementación.
También ayudan a percibir los flujos posibles entre casos de uso: un caso de uso solo podrá ejecutarse si anteriormente, otros casos de uso han dejado el sistema en un estado tal que éste pueda ejecutarse.

miércoles, 29 de abril de 2009

Avances de UML: Modelado en Colores (Parte 1)

UML tal y como se lo usa en la mayoría de lo casos, nos permite mantener un nivel de abstracción que elegimos nosotros mismos. Y lo elegimos según cual sea el nivel de detalle que nos interese percibir en un determinado modelo. Por ejemplo, en una clase de análisis, no nos importa conocer el tipo de dato que un atributo puede tener; con saber con el atributo existe nos basta; e incluso, si nos abstraemos más aún, podemos lograr que ese mismo atributo sea totalmente irrelevante, a tal punto que desaparezca por completo de la clase (aunque cuidado, para niveles menores de abstracción, éste seguirá existiendo).

Técnicas de abstracción hay muchas, y más de una vez nosotros mismos tenemos nuestras propias formas “simplificar un modelo” aún sin pretenderlo conscientemente.

Como ejemplo, en UML, podemos agrupar los elementos que se pueden manipular como un todo en los llamados paquetes. Y esto, nos permite concentrarnos en el paquete como una sola cosa, y no como los muchos componentes que puede contener. Esto es realmente útil cuando tenemos demasiados elementos para analizarlos todos en detalles, y más aún, cuando algunos de esos elementos no los queremos analizar en detalle.

Utilizar paquetes, es sólo una forma de abstraernos de algunos aspectos del dominio. Seguramente existen muchas otras, pero sin duda una de las más interesantes, tiene que ver con el uso de colores en los diagramas de UML.

Peter Coad, Eric Lefevre y Jeff De Luca realizaron investigaciones sobre este último punto: el uso de colores para el modelado de sistemas. El lenguaje que utilizaron para “colorear” fue el Lenguaje Unificado de Modelado (UML). El resultado de estas investigaciones, es una notable técnica, que nos permite identificar a simple vista, los distintos tipos de elementos que existan en un dominio de negocio dado, y además nos permite saber qué tipos de elementos son. A este “tipo de elementos” ellos les llamaron: arquetipos. (“archetypes”, en inglés). En su libro “JAVA Modeling COLOR with UML” ([Coad99]) explican con detalle ésta técnica.

Esta técnica de coloreado nos permite analizar un modelo y entenderlo rápidamente por encima. El hecho de usar color en un modelo –por ejemplo, en un diagrama de clases- no da una perspectiva general de cómo está conformado el modelo, aún antes de mirarlo con detalle, porque como veremos más adelantes, estos modelos siguen un patrón genérico llamado “Componente de Dominio Neutral” (Domain-Neutral Component).

Esta técnica, además de ayudar a quién examina un modelo, también ayuda a diseñar modelos. Esto es así porque si tenemos en cuenta que los procesos de negocio siguen ciertos patrones (algo que Coad y los otros notaron), entonces se puede armar un modelo con sólo identificar las partes del dominio donde se pueden ajustar esos patrones.

(continuará..)

jueves, 26 de marzo de 2009

¿Generalizacion o Inclusion? Esa es la cuestion.

Esta pregunta surgió en un curso de Diseño de Sistemas, en tanto la profesora pretendia poner a prueba los conocimientos conceptuales supuestamente adquiridos por los alumnos en el curso anterior de Analisis de Sistemas. Todos tiraban ideas, pero costo un buen tiempo entre los cincuenta alumnos llegar a una conclusion importante.

Podemos imaginarnos el siguiente diagrama de Casos de Uso. Si la descripcion del sistema dice que “los pacientes pueden internarse por obra social o de forma particular”, es casi evidente –intuitivo incluso- pensar en una especialización de un caso mas general denominado “Internar”. Algo así:

Esto a simple vista nos resulta correcto, aceptable y hasta tipico y seguimos adelante. Pero la pregunta que podria surgirnos es. ¿Por que especializamos? ¿Por que no incluimos? Es decir, ¿estaria mal el siguiente diagrama?
Que diferencia presenta con el anterior, si ambos pueden hacer exactamente lo mismo. Para asegurarnos de esto, recordemos que es una generalizacion y que es una inclusion.

Inclusion: Es una forma de interaccion, un caso de uso dado puede "incluir" otro. El primer caso de uso a menudo depende del resultado del caso de uso incluido. Esto es util para extraer comportamientos comunes desde multiples casos de uso a una descripcion individual, desde el caso de uso que lo incluye hasta el caso de uso incluido. El comportamiento del caso incluido es colocado dentro del comportamiento del caso de uso base. No hay parametros o valores de retorno.

Generalizacion: Un caso de uso dado puede estar en una forma especializada de un caso de uso existente. Esto se asemeja al concepto orientado a objetos de sub-clases. En la practica puede ser util generalizar comportamientos comunes, describirlos una vez, y enfrentarse a los detalles excepcionales en los casos de uso especializados. Entonces la Generalizacion es la actividad de identificar elementos en común entre conceptos y definir las relaciones de un concepto general y un concepto especializado. Es una manera de construir clasificaciones taxonomicas entre conceptos.

Ya tenemos definidos ambos tipos de relaciones. Las definiciones parecen indicar que estos conceptos son bastante diferentes el uno del otro, y, de hecho los son, pero ¿donde radica la diferencia en el ejemplo dado? Es posible implementar un sistema usando el modelo con generalizacion, y funcionaria de la misma manera que si se implementara el modelo de inclusion.

En el primero, el paciente va a internarse activando el CU “Internar”. Supongamos que el paciente tiene una obra social: entonces el C.U. que se activa es “Internar con Obra Social” aplicando los pasos generales de “Internar” y en el punto indicado se siguen los pasos que pertenecen a la especializacion que, en este caso, se es “Internar con Obra Social”.

En el segundo modelo, el paciente activa directamente el caso de uso “Internar con Obra Social”, el cual realizara los pasos referidos a una internación con obra social llamara al caso de uso “Internar” en el momento que deba realizar los pasos generales.
Como vemos, ambos funcionan sin problemas. La pregunta –insisto- es: ¿porque el segundo no se utiliza?

Dejo abierta la pregunta para quien quiera pensarlo un poco.
Saludos.