Módulos en GeneXus X
Hace unas semanas tuve la suerte de participar en una charla con integrantes del grupo de desarollo de Artech, donde contaron como van a incorporar un nuevo tipo de objeto en GeneXus, el objeto Modulo. (no se como se va a llamar oficialmente)
Como lo habia escrito en el 2008 en la entrada A falta de modulos, buenos son los folders, me gusta mucho el tener modularizadas las KB, pues deberia facilitar bastante la forma en que desarrollamos nuestras grandes aplicaciones.
Algunas de las cosas que podrian implementarse:
1) Si no se definen módulos, todo sigue funcionando como hoy.
2) Si la KB se modulariza, puede definir objetos publicos y privados dentro de los mismos.
3) Todo objeto pertenece a un modulo y es privado o publico.
4) Pueden existir modulos dentro de modulos, definiendo una jerarquia.
Que implicancias puede tener esto?
Menos errores.
En la practica, puede cambiar mucho, ahorrando errores de dependencias no queridas entre módulos y haciendo que al cambiar algo interno de un modulo, no produzca errores colaterales no deseados.
Por ejemplo, cuando edito un objeto y quiero agregar una referencia a otro, solo me mostrara los objetos de mi modulo mas los objetos públicos de otros módulos, reduciéndose muchísimo el conjunto de objetos referenciables. Al tener menos opciones, vamos a producir menos errores.
Va a ser mas facil entender las KB.
Hoy es extremadamente dificil entender una knowledge base, cuando se superan los 2000 objetos. Me considero un desarrollador GeneXus bastante ducho pero cuando tengo que entender una KB de muchos objetos, me cuesta bastante entender la relaciones entre objetos. Cuando el modelo de datos es grande, directamente es complicado encontrar todas las relaciones, haciendo que se cometan errores.
Desarrollo particionado.
El tener módulos, posibilitara que el desarrollo se realice en forma mas compartimentada. Por ejemplo, una gran empresa, tiene una KB con todos sus sistemas en un modelo consolidado. Quiere contratar a empresas independientes para el mantenimiento de la misma.
Con los módulos, es mas fácil darle solo la parte de KB que necesite cada uno. Al tener bien definidos los objetos públicos se tendrán también mejor delimitados las interfaces de un modulo con el otro.
Focalización del testeo.
Uno de los problemas de los grandes sistemas (no solo los desarrollados con GeneXus) es que es imposible probar todo, pues nunca son suficientes los recursos para hacerlo. Siempre se hace una prueba parcial de los objetos antes de una liberación. Los objetos públicos, serán aquellos que pueden afectar a mas de un modulo en caso de modificar su funcionamiento, haciéndolos buenos candidatos para las pruebas de regresión.
Un ejemplo
En una KB grande, hay un conjunto de objetos que son los que definen y manejan los usuarios, el login, el recordar contrasena , etc.
Si defino que todos los objetos pertenecen al modulo SEGURIDAD, puedo marcar todos los objetos como privados y unicamente marcar como publico el webpanel de login.
Los demás desarrolladores de la KB solo verán el objeto login para hacerle call y no podrán invocar a los objetos privados.
Esto me permitiría modificar la forma en que manejo los algoritmos internos (por ejemplo, como almaceno la contraseña encriptada) sin afectar a nadie mas en la KB.
En GeneXus muchas cosas tendran que cambiar para soportar los modulos.
Por ejemplo se van a necesitar:
* Agregar propiedades de publico/privado
* Nuevo tipo de objeto modulo.
* Reportes de objetos privados invocados desde otro modulo
* Reportes de objetos publicos que nadie invoca (es un warning)
* Diagrama de invocacion entre modulos
El tema de para mucho y también va a cambiar bastante la forma en que desarrollamos, pues los escenarios de uso son variados. Si tienen alguna idea o sugerencia para hacer, podemos discutirla de forma de formalizar los pedidos.
Aclaro por las dudas que no se si van a terminar implementándose los módulos y tampoco conozco en que versión de GeneXus van a salir.
Como lo habia escrito en el 2008 en la entrada A falta de modulos, buenos son los folders, me gusta mucho el tener modularizadas las KB, pues deberia facilitar bastante la forma en que desarrollamos nuestras grandes aplicaciones.
Definiciones:
Modulo: Conjunto de objetos definido por el usuario.
Objeto Publico: Puede ser llamado/utilizado/referenciado por objetos de otros modulos y del mismo modulo
Objeto Privado: Solo puede ser referenciado dentro del mismo modulo
Algunas de las cosas que podrian implementarse:
1) Si no se definen módulos, todo sigue funcionando como hoy.
2) Si la KB se modulariza, puede definir objetos publicos y privados dentro de los mismos.
3) Todo objeto pertenece a un modulo y es privado o publico.
4) Pueden existir modulos dentro de modulos, definiendo una jerarquia.
Que implicancias puede tener esto?
Menos errores.
En la practica, puede cambiar mucho, ahorrando errores de dependencias no queridas entre módulos y haciendo que al cambiar algo interno de un modulo, no produzca errores colaterales no deseados.
Por ejemplo, cuando edito un objeto y quiero agregar una referencia a otro, solo me mostrara los objetos de mi modulo mas los objetos públicos de otros módulos, reduciéndose muchísimo el conjunto de objetos referenciables. Al tener menos opciones, vamos a producir menos errores.
Va a ser mas facil entender las KB.
Hoy es extremadamente dificil entender una knowledge base, cuando se superan los 2000 objetos. Me considero un desarrollador GeneXus bastante ducho pero cuando tengo que entender una KB de muchos objetos, me cuesta bastante entender la relaciones entre objetos. Cuando el modelo de datos es grande, directamente es complicado encontrar todas las relaciones, haciendo que se cometan errores.
Desarrollo particionado.
El tener módulos, posibilitara que el desarrollo se realice en forma mas compartimentada. Por ejemplo, una gran empresa, tiene una KB con todos sus sistemas en un modelo consolidado. Quiere contratar a empresas independientes para el mantenimiento de la misma.
Con los módulos, es mas fácil darle solo la parte de KB que necesite cada uno. Al tener bien definidos los objetos públicos se tendrán también mejor delimitados las interfaces de un modulo con el otro.
Focalización del testeo.
Uno de los problemas de los grandes sistemas (no solo los desarrollados con GeneXus) es que es imposible probar todo, pues nunca son suficientes los recursos para hacerlo. Siempre se hace una prueba parcial de los objetos antes de una liberación. Los objetos públicos, serán aquellos que pueden afectar a mas de un modulo en caso de modificar su funcionamiento, haciéndolos buenos candidatos para las pruebas de regresión.
Un ejemplo
En una KB grande, hay un conjunto de objetos que son los que definen y manejan los usuarios, el login, el recordar contrasena , etc.
Si defino que todos los objetos pertenecen al modulo SEGURIDAD, puedo marcar todos los objetos como privados y unicamente marcar como publico el webpanel de login.
Los demás desarrolladores de la KB solo verán el objeto login para hacerle call y no podrán invocar a los objetos privados.
Esto me permitiría modificar la forma en que manejo los algoritmos internos (por ejemplo, como almaceno la contraseña encriptada) sin afectar a nadie mas en la KB.
En GeneXus muchas cosas tendran que cambiar para soportar los modulos.
Por ejemplo se van a necesitar:
* Agregar propiedades de publico/privado
* Nuevo tipo de objeto modulo.
* Reportes de objetos privados invocados desde otro modulo
* Reportes de objetos publicos que nadie invoca (es un warning)
* Diagrama de invocacion entre modulos
El tema de para mucho y también va a cambiar bastante la forma en que desarrollamos, pues los escenarios de uso son variados. Si tienen alguna idea o sugerencia para hacer, podemos discutirla de forma de formalizar los pedidos.
Aclaro por las dudas que no se si van a terminar implementándose los módulos y tampoco conozco en que versión de GeneXus van a salir.
Excelente!! va a ser una de las características esperadas para el próximo encuentro me imagino :)
ResponderBorrarAlgo que aún no visualizo es el tema de la dependencia con el acceso a datos a nivel de módulos.
Si tengo módulos en una KB, y todos dentro de esa misma KB tienen libre acceso al modelo de datos, puedo estar en problemas si genero módulos con cohesión por ese lado.
Una característica que incorporaría sería poder declarar a nivel de Transacción GeneXus o Tablas sobre cuales "Módulos" permito que se acceda.
La otra es hacer que para cuando se usa módulos usar ese sistema de asignación simplemente uniendo esas transacciones dentro de un módulo, solo que con esa asignación simplemente se declararía el concepto privado.
Con esto logramos que ciertas tablas sean internas dentro de un módulo, y las "públicas" no existan, que se tenga que usar interface para acceder a las mismas (dataproviders?, procedimientos?).
Hoy es muy complejo controlar todos los puntos de escape, cuando un producto se hace grande se requiere que se hagan esas soluciones en el inicio, impidiéndole en el desarrollo (y no creando herramientas por fuera que hagan esos análisis aplicando políticas que no están declaradas nativamente en el lenguaje).
Me imagino que estarán pensando también en algo que impida que cualquiera cambie definiciones a nivel de módulo, o por lo menos vean de pensar en incorporar algún mecanismo de "autenticación".
Porque suele suceder que cuando una herramienta no permite a un programador hacer algo y ese programador "a la apurada" quiere salir del paso.. un mensaje que le diga "no puede usarlo porque no es del módulo X o porque no está público el programa Y", lo primero que va a hacer es entrar al módulo y dejarlo público, rompiendo con "directivas" declaradas por otros.
(y que después se volvería complejo detectar quienes tocan, cuando y porqué)
Lo otro que estaría bueno de ver es cómo afecta el uso de módulos a la UTL, puede ser que procesos de módulos puedan estar dentro del compromiso o no (libre albedrío de los commit y rollback).
Estaría bueno que se pensara también algo por ese lado (sé que igual se puede hacer manual a nivel de cada interface pública, pero sería interesante ver de si es posible definir decisiones "generales" sobre un módulo)
De todas formas, teniendo en un principio lo mencionado en el post, ya estaría muy contento.
Ya estaba pensando en comenzar a declarar mis módulos con ExternalObject invocando a programas GeneXus (alternativa no recomendada?)...quedo a la espera de una mejor solución ;) (Evo II? o lo tendremos para la Evo I? mmm.. me muero por tenerlo ya en la Evo I)
David:
ResponderBorrarEl acceso a datos (directo e indirecto) fue un tema que llevo bastante tiempo en la reunion y aun no estaba definido como se va a implementar.
Una de las posibilidad es incluir las Tablas en los modulos, de forma que si una tabla es privada, solo puede hacerse un for each sobre esa tabla, dentro del modulo que la contiene.
Si la tabla es publica puede ser accedida por cualquier objeto.
Desde mi punto de vista, los dataproviders pueden ser los objetos que los modulos publiquen para que los demas accedan a los datos del modulo.
Se complica con el tema de la integridad referencial, pues no hay forma (hoy al menos) de evitar que una transaccion acceda a las tablas de otro modulo, cuando tiene que chequear que un determinado valor, no esta siendo usado en otra tabla de otro modulo. Creo que es algo muy manejable.
No entendi tu planteo de la relacion UTL y los modulos. Me estoy perdiendo algo?
En cuanto a lo que planteas de la seguridad (autenticacion/autorizacion) creo que la idea era mantener lo que hay hoy, o sea, tener autenticacion (quien hizo los cambios) pero no manejar autorizaciones en GeneXus.
Pueden existir diversas formas de integrar un modulo a una KB. Una puede ser como objeto externo, otra como objetos que no puedo modificar, objetos normales, etc..
Conviene plantear cuales serian los escenarios de uso y ver si todos pueden ser resueltos.
Gracias por el comentario
Enrique, lo que me refiero con los módulos y la UTL me refiero a algo similar a "Execute in new LUW" con algunos sabores de las propiedades de commit on exit.
ResponderBorrarVan algunos ejemplos:
Por un lado me gustaría definir que todos los programas de un determinado módulo no tengan permisos de commit ni rollback (afectar UTL?).
Con esto me aseguro que nadie por error en un módulo que corre dentro de una UTL (orquesta) me genere problemas con los commit o rollback's.
No me importa a que nivel se haga el control, hoy tengo algo que por fuera tengo identificados esos programas y los controlo con un analizador.
Dentro de GX me lo imagino simple.
2 opciones, una que el generador tome por ley una definición de si el módulo permite que los procesos controlen la utl (permitir o no el uso de commit ni rollback ni commit on exit), y una opción que diga.. commit on exit a nivel de las interfaces públicas (en el caso de que quiera que siempre en la salida de las interfaces se haga commit automáticamente o que la interface sea quien controle el commit/rollback).
Otro es el caso de módulos que tienen su propia unidad lógica de trabajo (LUW).
O sea, ellos controlan internamente su commit/rollback, los cuales no afectan a los UTL's de quienes lo invocan.
Si un módulo lo defino como "Execute in new LUW" no tengo la necesidad de definir la misma a nivel de cada interface externa del módulo.
Me cuesta ver la relacion entre las UTL y los modulos.
ResponderBorrarPara mi deberiamos tener herramientas para ver y manejar UTL en GeneXus pero no veo claramente como relacionarlo con los modulos.
Entiendo tus ejemplos, pero me parecen temas que es mejor resolverlos en forma independiente.
A que te refieres con "independientes"?
ResponderBorrarHoy tengo problemas por no tener algo declarado nativamente a nivel de GeneXus, si GeneXus me permitiera a nivel de la metadata de algo almacenado dentro de la KB controlar o no permitir algo (o que el generador tome acción basada en una propiedad de contexto), simplemente todos los que estén usando esa KB aplicarán sobre la misma regla.
De lo contrario, si dependo de extensiones o herramientas externas.. termino en la misma, controlando en todos los posibles puntos de falla. No tengo otra forma de asegurar que "de fábrica" o por definición las cosas se hagan correctamente.
Cuando tienes un equipo de desarrollo grande sobre un producto muy grande (+50 programadores en varias KB's de +10.000 objetos GX), son esas "pequeñas ayudas" las que realmente hacen la diferencia (ahorran tiempo y trabajo al no permitir que las cosas se hagan mal desde un principio).
Si directamente tengo declarado que algo dentro de un módulo X no se generará jamás con commit, me aseguro que el desarrollador se despreocupe del tema de cuando poner o no el commit, me aseguro también que no dependerá de si se acordó o no de ponerlo, y me aseguro que cuando él haga las pruebas en su ambiente local de algo generado en su GX instalado esté probando exactamente lo mismo que cuando pase a ser parte del consolidado principal.
Al ser además algo declarado nativamente por GeneXus, me aseguro que el generador/especificador tendrá en consideración éstos seteos, si nadie puede cambiar el comportamiento del módulo, me aseguro que nadie escapará de "la regla".
Si es sabido que errar es humano, entonces tenemos que buscar la forma de que esos posibles errores sean minimizados.
Un simple conjunto de reglas puede hacer que un programa con "seteos malos" nunca llegue a producción.
Entiendo la necesidad de controlar donde se ponen los commit, solo que no me imagino un modulo que no tenga commits.
ResponderBorrarHay objetos que pueden tener commits y otros que no, pero no lo veo asociado ni a los modulos ni a los objetos publicos o privados.
O sea veo eso como algo independiente a los modulos. Tengo que tener un mecanismos de que no metan mas commits de los necesarios y que no saquen los que ya estan y enterarme cuando se viola esta regla, pero como te dije antes, no la veo asociado a los modulos.
Seguramente me esta faltando visualizar algo..
descartemos mis sugerencias!!!
ResponderBorrarRealmente el problema viene por otro lado, no se soluciona en momento de generación, debería ser a nivel de lenguaje/runtime.
Con el amigo Marcos Begerez anduvimos discutiendo sobre el tema, y pensamos que existe forma de que sea solucionado por programación + runtime.
(vamos a enviar la sugerencia a la gente de desarrollo de Artech)
Yo no puedo descartarla, porque aun no logre entenderla bien!!.
ResponderBorrarTenemos varios problemas similares con el commit que se pone de mas o de menos, pero no logro ver su relación con el tema módulos..
Seria bueno que hicieran publica la idea del manejo del commit, para poder discutirla y enriquecerla publicamente.
Muy interesante el tema de los módulos sobretodo por las propiedades de público/privado de los objetos.
ResponderBorrarY como comentaron sería muy bueno tener la posibilidad de llevarlo al nivel de las tablas, donde todas tengan "permiso" de lectura aunque sean privadas para el resto de la KB, pero no de insert/delete/update.
De esta forma se evitaría también que se dupliquen objetos, porque si hay uno que es privado y no puedo usarlo, seguramente tendré que crear otro que haga lo mismo.
Javier:
ResponderBorrarAlgo hablamos sobre poder marcar una tabla como publica o privada.
Pero como vos bien decis, puede necesitarse algo adicional, para poder usar eso.
Tal como lo pienso yo, si quiero que una tabla pueda insertarse pero no borrarse desde fuera de mi modulo, yo pondria la tabla como privada, pero pondria un procedimiento/BC que permita hacer esa operacion como publico.
Con esta combinación, podría controlar lo que tu estas pidiendo, impidiendo que graben/borren directamente sobre la tabla con un new/for each, pero igual pueden usar la tabla en forma controlada.
La incorporacion de los modulos, no deberia llevar a la duplicacion de objetos que hagan lo mismo, sino todo lo contrario.
Si necesito un objeto privado de otro modulo, deberia evaluar si ese objeto esta en el modulo correcto, o si debería ser publico, pero NUNCA crear una copia del objeto que haga lo mismo.
Si un objeto tiene que ser usado en mas de un modulo, sera publico.
El solo hecho de saber que es publico, ya implica que lo tengo que tratar con mas cariño cuando haga cambio en el.