jueves, 28 de junio de 2007

Relación entre objetos y entes del dominio

Realmente se me hace difícil seguir una línea de conducción en lo que estaba escribiendo sobre el paradigma de objetos por el poco tiempo que le puedo dedicar, así que decidí cambiar un poco el enfoque y escribir sobre lo que estuve pensando en el día, para que salga más rápido y no tener el blog "dormido"... Así que aquí va lo que estuve re-pensando los últimos días y tiene que ver con tener un buen modelo de objetos.
Distinguir si se necesitan distintos objetos para representar distintos entes es generalmente sencillo. Es fácil distinguir que el objeto "1ro de Enero de 1997" no es el mismo que "2do de Enero de 1997". Son objetos distintos puesto que representan entes distintos, en este caso dos fechas y es sencillo ver que son dos entes distintos por su identidad.
El mayor problema está en descubrir aquellos objetos que no se ven en primera instancia, que generalmente están implícitos por cuestiones contextuales o de ambigüedad de lenguaje natural. Un ejemplo de ambigüedad del lenguaje natural se da con la palabra "día" en castellano, por ejemplo "¿Qué día es hoy?". La respuesta puede ser "Hoy es Lunes" u "Hoy es 25 de Junio del 2007". Está claro que "Lunes" y "25/6/2007" son entes distintos y por lo tanto deben ser representados por objetos distintos. Pero si el usuario en los requerimientos habla de "día", ¿a cúal se refiere? ¿al día de la semana, a la fecha, o a ambos y según el contexto se usa uno u otro?. No resolver este problema de ambigüedad, en definitiva de interpretación, puede llegar a generar grandes problemas en la evolución del sistema. (En inglés no se sufre de esta ambigüedad puesto que existen las palabras "Day" y "Date" para día y fecha)
Un ejemplo de entes implícitos es el concepto de "mes del año" del Calendario Gregoriano, por ejemplo "Febrero de 2004". Este es un concepto que generalmente no se reconoce en el modelo porque cuesta "verlo" en el dominio y se lo confunde con el concepto que representa un mes, por ejemplo "Febrero". Pero está claro que no podemos saber cuantos días tiene "Febrero", solo se puede saber cuantos días tiene "Febrero del 2004", o "Febrero del 2005", o sea, el mes del año. No "encontrar" estos objetos en el dominio implica que no serán modelados y hará que cuando se los necesite se terminen implementando soluciones de compromiso, repitiendo "código", etc.
Hay casos también donde se crean más objetos (en este caso conceptos) que los necesarios o definidos en el dominio, o sea que se crean más abstracciones de las necesarias. (Hasta ahora no hable sobre las Clases, pero me refiero a ello). Por ejemplo, al modelar un Autómata Finito Determinístico [1] uno de los problemas que surgen es si se debe crear una abstracción para el "Alfabeto". Un alfabeto (para el contexto del autómata) no es más que un conjunto de símbolos, y ya existen abstracciones para representar conjuntos, por ejemplo en Smalltalk es la clase Set, es por ello que se debe, para este caso, utilizar un Set para representar un Alfabeto y no crear una nueva abstracción (clase) "Alfabeto" que solamente agregaría complejidad al modelo. O sea, se puede ver que el nombre Alfabeto es puramente contextual a la definición del Autómata.

En definitiva, a lo que quiero llegar y aún me cuesta probar formalmente es que para mi tener un "buen" modelo implica tener un isomorfismo entre los objetos del modelo y los entes del dominio. Esto significa que por cada ente del dominio hay un único objeto que lo representa. Esto pasa para objetos concretos (por ejemplo "Lunes") como para entes abstractos o conceptos (por ejemplo "Día").
Si logramos tener este isomorfismo entre el modelo y el dominio, cada vez que realicemos una observación del dominio puede suceder lo siguiente con el modelo:
1) Que dicha observación sea modelada sin ningún problema, o sea, el modelo la contempla de tal manera que por cada ente de dicha observación tengo un objeto en el modelo que lo representa y esta nueva observación es un caso contemplado por el modelo.
2) Que dicha observación no pueda ser resuelta en el modelo. Esto implica que el modelo no es lo suficiente maduro aún, que el estado del conocimiento que dicho modelo representa no es completo respecto del dominio de problema. Para soportar esta observación puede ser necesario:
a) Crear nuevos objetos o conceptos únicamente. Este es el mejor caso, indica que el modelo esta por buen camino, que está madurando bien
b) Tener que partir objetos y conceptos ya existentes en otros más "chicos", más cohesivos. En este caso el modelo aún está un poco inmaduro.
c) Tener que juntar objetos y conceptos ya existentes en otros más generales. Esto es muy raro que suceda puesto que implica que se hizo una "factorización" excesiva, lo cual es muy raro.
d) Cualquier combinación de los tres puntos anteriores.

En fin, mucho para pensar al respecto, pero básicamente quería hacer este comentario sobre el isomorfismo que me parece interesante.
También me parece que utilizar la palabra "bueno" para calificar un modelo es difícil de consensuar. Ultimamente me estoy tirando más por usar "completo" o "maduro", y de estas dos me gusta más "maduro" puesto que "completo" denota la idea de "cerrado", de no necesitar más cambios, algo muy difícil de lograr más aún si suponemos que constantemente se aprende algo nuevo.
Otra idea interesante es pensar en el grado de madurez de un modelo como en función a los cambios que necesita cada vez que se realiza o aparece una nueva observación del dominio que representa. La idea es que esta función debería tender a cero a medida que crecen las observaciones. Si esto no se da, el modelo está en problemas...

[1] El ejercicio de modelar un Autómata Finito Determinístico se le ocurrió a Dan Rozenfarb en la materia de POO. Es un ejercicio muy interesante puesto que la definición al ser matemática, o sea formal y sin ambigüedades, permite un traducción directa al modelo de objetos. La definición es la siguiente:
Un autómata finito determinístico (o AFD) es una 5-upla (Q,
S, d, q0, F) cuyos elementos son:
Q = {q0, q1, q2, ...} es un conjunto finito, no vacío, de estados.

S
= {a,b, ...}, llamado alfabeto, es un conjunto finito de símbolos de entrada.
d
: Q x S -> Q es una función de transición, también denominada control finito.
q0
pertenece a Q es el estado inicial.
F
incluído en Q es el conjunto de estados finales.
Lo más importante es saber si un AFD acepta o no una secuencia de caracteres

2 comentarios:

Anónimo dijo...

Tu artículo es muy interesante, pero deberías concentrarte un poco más en la práctica. Filosofas demasiado y no concretas mucho. Inicié la lectura con la espectativa de determinar la forma como ibas a modelar un autómata con POO y al final te quedaste con una definición meramente matemática.

Hernan Wilkinson dijo...

Que tal Anónimo, una lástima que no digas quién sos para poder hacer un ida y vuelta interesante.
En otras entradas del blog hay ejemplos bien concretos que espero te sirvan.
Respecto de modelar el autómata con Objetos, justamente la definición matemática alcanza si seguís los consejos que doy... igual voy a ver si tengo tiempo y lo escribo hasta usando TDD asi que stay tuned!