Modularización de KB orientada a los datos.
Después de probar varias formas de modularizar, la que mas me convence es hacerla orientada a los datos o las tablas del modulo.
Mi definición de modulo, seria:
Las excepciones, son objetos que hacen referencias a tablas de un modulo, sin pertenecer al mismo son:
* Transacciones con integridad referencial sobre las tablas del modulo.
* Join entre tablas de diferentes módulos
En un diagrama:
Y una tabla de Facturas
Mi definición de modulo, seria:
Conjunto de tablas, todos los objetos que hacen UPDATE/INSERT/DELETE sobre las mismas y casi-todos los objetos que hagan referencia a dichas tablas.
Las excepciones, son objetos que hacen referencias a tablas de un modulo, sin pertenecer al mismo son:
* Transacciones con integridad referencial sobre las tablas del modulo.
* Join entre tablas de diferentes módulos
En un diagrama:
GeneXus ya controla que no se puedan acceder a objetos privados (tablas u otros objetos) y da errores al especificar. Estos son los que estan a la izquierda.
Para todos los objetos publicos (no tablas) esto tambien esta bien manejado.
El problema para soportar nuestra forma de trabajo, viene con las tablas publicas.
Una tabla, no tiene modulo, ni es publica o privada en forma directa (lo cual creo que es una gran carencia en la forma de definir módulos). La tabla hereda el modulo de una de las transacciones que la definen (no es trivial saber cual es) y es publica o privada, dependiendo de como sean las transacciones que la definan. Si todas las transacciones paralelas son privada, la tabla es privada.
Si al menos una transacción paralela que defina la tabla es pública, entonces la tabla es pública. (Mas info aca)
Si al menos una transacción paralela que defina la tabla es pública, entonces la tabla es pública. (Mas info aca)
Que problemas trae este enfoque?
Es una recomendación importante, que cada modulo tenga la menor cantidad de objetos públicos, con lo cual es minimiza la el acoplamiento entre modulos.
En algunos casos, es dificil mantener objetos como privados, porque tengo que definir objetos publicos sin quererlo.
Puede quedar mas claro con un ejemplo
Tengo una tabla de Funcionarios
Funcionarios en Modulo Sueldos
*FuncionarioId
FuncionarioNombre
FuncionarioSueldo
Y una tabla de Facturas
Facturas en Modulo Facturacion
*FacturaId
FacturaFecha
FacturaImporte
FuncionarioId -- Funcionario que facturó
Al tener la transaccion de Facturas, integridad referencial sobre Funcionarios, debo poner como publica alguna transaccion que la defina.
Esto podria permitir que alguien escriba, en cualquier modulo
for each
FuncionarioSueldo = FuncionarioSueldo * 1.10
endfor
Entonces, para permitir un control de integridad referencial (algo bastante inofensivo, que no va a cambiar nada en las tablas del modulo), me pierdo de detectar referencias mucho mas peligrosas.
Tengo la transaccion
Por integridad referencial con otras tablas que tienen el OficinaID, debo poner la tabla Oficinas como pública. La forma que tengo de hacerlo, es poner la transacción que la define como publica, pero esto trae como efecto colateral (no deseado) que la tabla OficinaFuncionarios, queda como publica.
Una posible solución, es definir dos transacciones adicionales, para definir Oficinas y OficinaFuncionarios por separado y ponerlas con la propiedad GenerateObject=False, pero agrega objetos innecesario y complica demasiado.
Creo que seria bueno que para próximas versiones de GeneXus, se tuviera la posibilidad de poner tablas en módulos y marcarlas como privadas o publicas en forma directa y sin tener que hacerlo cambiando transacciones.
Esto podria permitir que alguien escriba, en cualquier modulo
for each
FuncionarioSueldo = FuncionarioSueldo * 1.10
endfor
Entonces, para permitir un control de integridad referencial (algo bastante inofensivo, que no va a cambiar nada en las tablas del modulo), me pierdo de detectar referencias mucho mas peligrosas.
Transacciones multinivel.
Otro caso parecido, pasa cuando se tiene transacciones de varios niveles.Tengo la transaccion
Oficinas *OficinaID OficinaNombre (*FuncionarioId //Funcionarios que trabajan en esa oficina FuncionarioFechaIngresoOficina)
Por integridad referencial con otras tablas que tienen el OficinaID, debo poner la tabla Oficinas como pública. La forma que tengo de hacerlo, es poner la transacción que la define como publica, pero esto trae como efecto colateral (no deseado) que la tabla OficinaFuncionarios, queda como publica.
Una posible solución, es definir dos transacciones adicionales, para definir Oficinas y OficinaFuncionarios por separado y ponerlas con la propiedad GenerateObject=False, pero agrega objetos innecesario y complica demasiado.
Creo que seria bueno que para próximas versiones de GeneXus, se tuviera la posibilidad de poner tablas en módulos y marcarlas como privadas o publicas en forma directa y sin tener que hacerlo cambiando transacciones.
Actualizaciones a tablas públicas.
Esto es algo bastante discutible, pero si pongo un tabla como publica, puede interesarme que igualmente no se pueda actualizar los datos, sino solo consultarla desde afuera del modulo.
Por ahora, le agregué al reporte ListModules del KBDoctor una columna para detectar esta situacion, pero tal vez seria buena considerarlo en el futuro desde GeneXus.
Hola Enrique aprovechando esta entrada en tu blog: Entiendo por lo que me ha indicado ARTECH en la versión Tilo el foco de los módulos es exclusivamente "Comprensión" de grandes KBs.
ResponderBorrarEso implica sí cambios en generación y demás.
Las funcionalidades de módulos que se están agregando en la 15 entonces van a ayudar muchísimo a quienes tienen que obtener una visión global de las KBs, viendo los distintos módulos que la componen y sus interfaces. Quienes comienzan a desarrollar, solo tendrán que entender su propio módulo y conocer las interfaces de los demás módulos; éstos además trabajarán más tranquilos dado que saben mejor medir el alcance e impacto de sus cambios.
Todo esto es base para en el futuro pensar en más escenarios.
Ahora bien realmente para que esto sea útil para las empresas que tenemos grandes KBs se hace necesario evaluar más escenarios específicamente la protección de módulos, o protección de los desarrollos, hay que pensarlo nuevamente a la luz de estos avances y ver si estos avances en módulos nos ayudan a esto, lo veo como el API del GAM y del GXFLOW, veo problemas en la distribución de los módulos de GX15 el no poder hacerlo si maneja tablas, si se quiere que verdaderamente un Núcleo similar al concepto del STONE FRAMEWORK se distribuya a un programador debe llevar todas las entidades afectadas por dicho módulo en dicho proceso.
Veo el tema de los módulos más como servicios a exponer y ser consumidos, el tema de las entidades intermodulares es algo que debe ser evaluado a fondo orientado a los datos como indicas. Pero si sería extraordinario que el mismo GeneXus nos ayudará con la administración de esto, más aún cuando entre más tiempo las KBs siguen creciendo, el modularizarla no solo se vuelve útil para comprenderla si no también para administralas, cada Módulo debe exponer los Servicios que provee y debería ser como APIs (Como actualmente se maneja en el FLOW y GAM)
Toda administración de módulos debe ir de la mano con GxServer administrando cada uno de los módulos y como sucede con el API del GAM y GXFLOW las tablas sean generadas como pasan en estas aplicaciones.
Neftaly, el estado actual de los Modulos en GeneXus, si bien no es optimo, creo que mejoran mucho la forma en que se organizan KB grandes. Esto sirve tanto para su comprension, asi como para ayudar al mantenimiento de las mismas.
ResponderBorrarAl tener delimitado el alcance del cambio que se realiza, es mas facil probar que el cambio fue exitoso, y se puede ir mucho mas rapido.
Pasar de una KB sin modulos (mejor dicho, con un solo modulo) a una modularizada, duele un poco, pero con metodologia se logra sin problemas. El marcar como privados los objetos tambien trae algunos dolores de cabeza pero tambien puede lograrse.
Creo que la funcionalidad de modulos, esta lo suficientemente madura como para que pueda ser usada en grandes KB. Aun tiene varios inconvenientes con GXServer pero confio que estos "errores" puedan solucionarse en las proximas versiones.
En el futuro, podremos distribuir los modulos en forma binaria, pero como estan ahora, ya aportan mucho valor.