Usando dominios enumerados en Genexus


Uso bastante los dominios enumerados cuando programo.
Creo que ayudan mucho a dejar mas clara la programación pues se hace explicito el uso de determinados valores (evitando asi tener que poner constantes o parámetros en los programas) y luego es fácil buscar por ellos.

Un buen ejemplo es el de manejo de Estados de algun objeto, por ejemplo las solicitudes de trabajo:
Se puede tener la solicitud ingresada, en curso, anulada y cerrada.

Para esto generalmente defino dominios con valores enumerados, y en el codigo hago referencia a EstadoSolicitud.Anulada en vez de 'A' que queda mucho menos claro.

Cual es la contra de este enfoque?.
Si a la solucion se le quiere brindar cierto grado de personalizacion, hay que permitir que el usuario en tiempo de runtime agregue nuevos estados a las solicitudes. Esto implica que tenemos que definir una tabla que tenga "repetida" la informacion de Estadoo, Descripcion del estado de la solicitud.

Al tener cosas repetidas, siempre surge el problema de que alguna de las dos este equivocada, cosa que puede suceder si me cambian la descripción de la tabla para el registro que internamente estoy usando como Anulado.

Para mejorar algo las cosas, habría que tener una función que permitiera desde un valor del Att/dominio, devolver la descripción, de forma de poder usarlo en la transacción para obligar o no dejar cambiar los valores "reservados" por la lista enumerada y de esta forma al menos, obligar que tengan los mismos valores.

De cualquier forma, todavia no consigo una solucion que me convenza totalmente y eso me hace enojar bastante.

Alguien ha sufrido lo mismo?

Encontraron alguna solución?

Comentarios

  1. Además del problema que planteas hay otro (peor creo), que es el que tengas un Enum con los 12 signos del zodiaco (por ejemplo) y tengas que hacer numerosas cargas de datos de ficheros externos, asi no puedes hacer esto:

    CliHor = &DatoLeido

    Sino que:

    if &DatoLeido ="AR"
    CliHor = Horoscopo.Aries

    etc...

    (se puede hacer un do case, pero el problema es el mismo).

    En fin, otro fallo de GeneXus a consecuencia de lo poco que saben de la vida real los que lo desarrollan.

    ResponderEliminar
  2. En Java uso un concepto de enumerado similar al que planteas, la diferencia es que si los valores pueden cambiar lo defino como una entidad persistente con su propia tabla y un ABM.
    Es decir, para mi los enumerados son estáticos, por ejemplo Sexo y Estado Civil; en otro caso es una entidad mantenible en la que defino constantes para los códigos que luego utilizo para consultar la descripción.
    Para evitar realizar tantos selects configuro mi entidad como cacheable y queda en memoria, obviamente es algo propio del framework que uso y no recuerdo si Genexus ofrece algo equivalente.
    No se si interpreté bien el problema que planteas…

    Saludos

    ResponderEliminar
  3. Comparto totalmente la opinión del usuario anónimo.

    ResponderEliminar
  4. Anonimo(s):
    Me parece que es bueno plantear cuales son las dificultades que se encuentran en el desarrollo de aplicaciones con GeneXus (o con la herramienta que utilices).
    NO comparto el tono de plantearlo. Desde mi punto de vista, es preferible plantear soluciones (lo que mas te sirva a vos) y en mi experiencia personal, si se plantean cosas razonables, se implementan.

    ResponderEliminar
  5. Federico:
    Creo que interpretas bien el problema.
    Con Genexus tambien tenemos cache de sentencias, para poder evitar los selects y mantener los valores en memoria.

    Trabajando con Hibernate, tenes algunas libertades mayores, pero creo que los problemas son similares.

    Gracias por el comentario.

    ResponderEliminar
  6. Con respecto al comentario del primer anónimo, yo lo que haría es lo siguiente:

    CliHor = Horoscopo.Convert(&DatoLeido)

    y me evitaría tanto los Ifs como los cases...

    También, de acuerdo con Enrique, es bueno plantear el problema, creo que no es la manera.

    ResponderEliminar
  7. Es posible obtener la descripción correspondiente a un valor de un dominio enumerado utilizando el método EnumerationDescription() como en el siguiente ejemplo:

    &Description = SignoZodiaco.EnumerationDescription( SignoZodiaco.Aries)

    El parámetro de EnumerationDescription tiene que ser un valor del domino (Constante, variable, etc.). Si no lo es, retornará el string vacío.
    -----------
    En corto plazo estaremos incluyendo una forma de recorrer los valores de un dominio enumerado programáticamente. Creo que esto puede ser de utilidad para validar que no se modifique la descripción de los registros que pertenecen al dominio.
    -----------
    Con respecto a anónimo: basta definas &DatoLeido como perteneciente al dominio Horoscopo para que la asignación funcione. Si eso no es posible, entonces deberías seguir la sugerencia de gml.

    ResponderEliminar
  8. Gonzalo:
    NO conocia el convert.

    Gustavo:
    Tampoco conocia el EnumerationDescription()

    Es bueno tener un blog para aprender cosas..

    Es bueno saber que se va a poder recorrer los enumerados para saber que valores tienen.. Esto va a ser para el U3 de la X?.

    ResponderEliminar
  9. Querido EA(rtech):
    Se paga por un producto terminado.
    Nosotros no tenemos que plantear la solución. Ellos proponen una solución a medias que termina NO sirviendo.

    Y siempre existen soluciones para versiones siguientes o futuras.

    ResponderEliminar
  10. Anónimo (respecto al ultimo comentario)
    Bienvenido al mundo del software!!!
    Asi funciona la ingeniería del software, me atrevería a decir no existe un solo software en el mundo cuyo autor pueda decir está 100% terminado, libre de errores, nunca nacesitaremos sacar la version X.1, etc. Es lo que hay al momento, quizá en un futuro esta ingeniería madure lo suficiente como para mejorar sustancialmente eso, pero deberá pasar mucho tiempo para que eso suceda. Y claro que las mejoras son para la "siguiente" versión, deberías leer el contrato antes de darle "Aceptar".

    Salu2

    ResponderEliminar
  11. El método EnumerationDescription es natural que no lo conocieras. Por error mio no salió documentado. Está disponible en la X desde el 9 de Setiembre de 2007!

    El método convert está desde la 9.0.

    El método para poder recorrer los dominios espero que esté en el U3, si.

    ResponderEliminar
  12. Aluziner:
    Comparto tu comentario.
    De todas las herramientas que uso (de software y de las otras) trato de encontrarle su mejor uso. Si ademas uso esa herramienta para ganarme la vida, trato que la misma sea lo mejor posible, para vivir mejor y trabajar menos.

    GP:
    Gracias por las aclaraciones. Esperemos el U3.

    ResponderEliminar
  13. Para los casos en que es necesario customizar los valores de un dominio o donde existe la posibilidad de que el usuario defina nuevos valores lo resolví de la siguiente forma:

    1) Una tabla de dominios
    2) Una tabla de valores de dominios

    DOMCAB
    *DomCod - Código de dominio
    DomDes - Descripción de dominio

    DOMVAL
    *DomCod - Código de dominio
    *DmvCod - Código de valor
    DmvDes - Descripción del valor
    DmvRes - Reservado (Si/No)
    DmvOrd - Orden de publicación
    DmvFil - Apto para filtro
    DmvAct - Activo

    Un usuario solo puede insertar y modificar registros no reservados. Un administrador puede manejar todo.

    Debe tener un indice Unique por: DomCod, DmvDes

    DmvOrd sirve para cargar los valores en un combo y presentarlos en un orden deseado.

    DmvFil sirve para los casos en que un combo con los valores del dominio se presenta como filtro en un panel. En estos casos puede ser necesario adicionar al combo el valor "Todos", "Algunos", "Ninguno", "No definido", etc... A estos valores se los identifica con codigo DmvFil determinado. La rutina que se encarga de leer los valores a mostrar puede tener como parámetro el código de DmvFil a leer, entonces carga también esos valores.
    La rutina de lectura debe leer: Todos los valores de un determinado Dominio(DomCod), que están Activos(DmvAct), que tienen DmvFil=0 or DmvFil=ParametroDeInput, en el orden DmvCod DmvOrd

    Saludos
    Carlos Lucatti

    ResponderEliminar
  14. Anónimo:
    Estás sufriendo mucho.
    No se puede hablar de un software terminado. Solo se puede hablar de que una version de un software se ha terminado cuando cumple con los alcances propuestos previamente para ella.
    Relájate, ... y de paso, identifícate !

    Saludos
    Carlos Lucatti

    ResponderEliminar
  15. Carlos:
    Somos varios los que hemos hecho cosas similares a la solucion que planteas.. y al ser varios, creo que hay un patron que deberia poder resolverse de una forma mas general, o dicho de otra forma, es algo que GeneXus podria permitir expresar en forma declarativa y no tener que programarlo en cada uno de nuestros sistemas...

    Una oportunidad de mejora.

    Gracias por el comentario.

    ResponderEliminar

Publicar un comentario

1) Lee el post
2) Poné tu opinión sobre el mismo.
Todos los comentarios serán leidos y la mayoría son publicados.

Entradas más populares de este blog

El Sordo

StackOverflow Documentation

Codigo simple