Modularizando bases de conocimiento.

Una de las funcionalidades mas promisorias de GeneXus X Evo3, es la posibilidad modularizar la KB.
Las ventajas son muchas, pero tener una KB bien modularizada, ayuda a entenderla, facilita mucho el mantenimiento y ayuda a instalar la aplicación.

Que es modularizar?

Dividir la KB en módulos (o grupos de objetos) de tal forma que sea mas fácil de entender, cambiar y manejar.



Porque modularizar?

  • Partiendo el problema y permitiendo resolverlo incrementalmente. 
  • Permite distribuir las tareas de desarrollo entre diferentes personas/equipos.
  • Definir interfaces claras entre dominios, facilita también la reutilización de un módulo en otro contexto del original. 

Dependencias. 

Decimos que un módulo depende de otro, o usa otro módulo, cuando llama o utiliza un objeto publico de otro módulo. 
Por ejemplo, si tengo un módulo A que tiene los objetos que hacen el manejo de parámetros de la aplicación y otro módulo B necesita recuperar el valor de un parámetro, decimos que el módulo B depende del modulo A

Para poder administrar una KB, conviene evitar que los módulos tengan dependencias cíclicas. 
No es bueno que A dependa de B y que B dependa de A, y se tratará de evitar siempre que podamos. 

Una modificación en A puede tener efectos en B y viceversa y seria bueno evitar esto.

Tampoco son buenas las cadenas de dependencias muy largas o profundas. 


¿Como hacer una BUENA modularización?


La división de una base de conocimientos en módulos, es una tarea subjetiva.   Muchas formas de dividir la KB pueden ser útiles y hay que elegir la que mejor sirva al grupo de desarrollo.

Voy a nombrar algunas características deseables de los módulos, sin mucho orden.

Cohesión. 

Es una medida de la interrelación que existe entre los objetos que componen un módulo.
Dentro del módulo, conviene tener objetos que estén relacionados entre si. Por ejemplo, puede verme tentado a tener dentro de un módulo, las rutinas que manejan Cotizaciones de Monedas y Parámetros del Sistema. Posiblemente convenga separar esto en dos módulos, pues son conjuntos de objetos con muy poca cohesión.
Si hacemos el grafo de llamadas entre objetos dentro de un módulo, si tenemos mas de un grupo de objetos desconectado, hay que evaluar dividir eso en varios módulos o submódulos.

Acoplamiento.

Es una forma de medir que tan dependiente es un módulo de los demás.
Para esto, se toman en cuenta las dependencias del mismo, diferenciando entre las dependencias SALIENTES de las ENTRANTES.





Inestabilidad. 

Se puede definir un indice de estabilidad, con la formula

IE = SALIENTES / (ENTRANTES + SALIENTES)

Donde un módulo que tenga solo componentes entrantes, como MOD_GL en la imagen, tendra un indice
MOD_GL IE = 0 / (3 + 0) = 0   => es un componente ESTABLE.

MOD_Proyectos = 2 / (2 + 2) = 0.5

MOD_Horas = 2 / (2 + 0) = 1 => es un componente INESTABLE.

Esto es solo una medida, que puede ayudar a identificar en que módulo hay que tener mas cuidado en su mantenimiento.

Interfaz

La interfaz de un módulo con el resto de la KB, son los objetos públicos del mismo.
Cada módulo, debería tener la menor cantidad de objetos públicos posible.
Una forma "fácil" de identificar cuales objetos deben ser públicos en un modulo, es marcar todos los objetos de un módulo como privados y hacer un REBUILD ALL. Ahí van a dar errores de especificación todos los objetos de otros módulos que necesiten usar algún objeto del modulo que estoy corrigiendo. Se vuelven a públicos los objetos llamados desde fuera. Es un proceso aburrido y que demora, pero es efectivo.
Dos indicadores útiles para módulos para medir el tamaño de su interfaz serian

OPub = Cantidad de Objetos públicos
IPub = Cantidad de Objetos públicos / Cantidad de objetos de módulo.

Otras características de módulos efectivos. 

  • Cada módulo tiene un conjunto de responsabilidades muy pequeño y bien definido.
  • Cada módulo tiene un nombre que permite identificar claramente sus responsabilidades.
  • Cada módulo provee una interface mínima y fácil de entender desde afuera, que exponga todas las operaciones que dicho módulo puede hacer. Es importante el nombre de los objetos que se expone, y los nombres de los parámetros que se utilizan. 

Como toda practica que tiene beneficios importantes, la militarización necesita trabajo para llevarla adelante. Hay que tener alguien en el grupo que este a cargo que la militarización se haga de forma correcta y efectiva.
En los próximas semanas/meses estaremos haciendo algunas herramientas (seguramente dentro del KBDoctor) para ayudar(me) a realizar esta tarea, pues es bastante consumidora de tiempo.

Estoy pensando hacer un reporte que muestren la lista de módulos e indicadores que incluyen

  • #Objetos
  • #Objetos Públicos
  • IPub = #Objetos Públicos / #Objetos Totales
  • Dependencias Entrantes
  • Dependencias Salientes
  • IE = Salientes / (Entrantes + Salientes)
  • #Componentes Conexos dentro del módulo.
  • Tiene dependencia cíclicla ?
  • Largo máximo de dependencias en la que participa.
  • El módulo tiene objetos públicos no referenciados por externos?

También un programa que recorra los objetos de un módulo y marque como privados aquellos que no son invocados desde afuera del módulo. Acá hay que tener cuidado con las transacciones y tablas, pues GeneXus hace un manejo difícil de entender para marcar las tablas como publicas o privadas. También hay un manejo de integridad referencial que no es trivial y obliga a marcar tablas como públicas aunque no deberían serlo.

En fin, el tema da para mucho y creo que vamos a tener que trabajar bastante en el futuro.

Comentarios

Entradas más populares de este blog

La nefasta influencia del golero de Cacho Bochinche en el fútbol uruguayo

Aplicación monolítica o distribuida?

Funcionalidades de GeneXus que vale la pena conocer: DATE Constants.