martes, 30 de marzo de 2010

Herencia en GeneXus

Cuando hablamos de herencia, en GeneXus, en general nos referimos a la herencia entre las distintas entidades. Por ejemplo, Estudiante es una Persona, y los defino con subtipos.

En este caso en realidad quiero hablar sobre la herencia entre objetos... que en GeneXus es prácticamente inexistente.

Lo único que existe (hasta donde yo se), son los objetos de tipo Style, donde se pueden definir propieades, componentes del form y eventos, que luego son heredados al crear un objeto basado en dicho style. El problema con esta herencia (para el código) es que es solo al momento de crear el objeto, pero luego no se mantiene. Además el código heredado queda en el objeto "hijo" como una copia del código del objeto "padre".

Sería bueno poder tener herencia de verdad. Es decir, tener un objeto que tenga el código común, y que los demás puedan heredar de este, sin copiar el código a cada uno de los objetos "hijos".

Un claro ejemplo de esto es en el pattern WorkWith, donde todos los objetos quedan con el código de paginado, es decir, los eventos First.Click, Next.Click, etc.

Obviamente esta herencia se debe poder sobreescribir en un objeto dado si así se desea. Por ejemplo podría tener un objeto que agrege código en el evento First.Click, o incluso que haga algo totalmente distinto.

Probablemente este tema no sea sencillo de solucionar, y hay cosas que hay que definir bien (herencia simple o múltiple, interfases, sintaxis para la funcionalidad nueva, etc.), pero me parece que es algo sumamente necesario.

10 comentarios:

  1. Está muy buena la propuesta.

    Creo que ayudaría a hacer más mantenible la aplicación. Con el enfoque actual (que se copia al momento de crear el objeto) se vuelve bastante complicado.

    ResponderEliminar
  2. Muy buena propuesta!!
    Hace un tiempo que se requiere de algo así en GeneXus (cansado de hacer refactoring?, dividir y replicar?).

    Hacer que GeneXus sea orientado a objetos ya me parece demasiado para las próximas versiones.

    Yo soy de la idea de ir hacia algo menos radical.
    Es posible implementar algo así si requerir de una implementación orientada a objetos para lograr algo similar a lo que se conoce como herencia.

    Adaptando un poco el lenguaje con anotaciones podría implementarse algo similar sin modificar demasiado el lenguaje actual.

    El generador lo que tendría que hacer es tener en cuenta las anotaciones y unir el código fuente de todas las herencias/extend y crear un único código fuente sobre el cual especificar/generar/compilar (visión "union").

    Interesante para ver de experimentar (me lo anoto).

    Estaría bueno conocer si la gente de Artech tiene pensado investigar o invertir en ir hacia algún tema relacionado con esto en algún momento.

    ResponderEliminar
  3. David: No me queda claro lo que decís de las anotaciones. ¿Tenés un ejemplo de como sería?

    ResponderEliminar
  4. jaja, ya nos vamos con una propuesta de implementación.

    La idea que tengo es más relacionado a "Templating" que al concepto de "Herencia".

    Simplificándolo, se "heredaría" del padre "el código" que sería del tipo "Template" al hijo (Aplicaría de forma Top/Down, herencia de herencia)

    Se declararía en los objetos cuales son los puntos en donde se puede "extender", en donde se podrá incorporar código. (Eso puede ser con anotaciones por ejemplo)

    Hay que modificar el IDE y los controles de GeneXus a efectos de que tengan conocimiento de secciones no modificables (código, variables, controles).

    En el fondo, el código fuente del objeto es la suma de los códigos (El form HTML es la suma de los códigos y los Printblock son las versiones modificadas o acumuladas).

    Si vieras el código que existe por detrás, verías muchas "anotaciones" que declaran esas secciones (que referencian de donde provienen).Patterns y otros usan ya un sistema de anotaciones similar.

    Cuando se modifica el padre, se ve quienes "heredan" del mismo y se regeneran, ya que se modificó el "template padre".
    Lo interesante es hacer Template de Template de Template... y hacer algo que evolucione compartiendo código en común.

    Es solo una idea, que en una de esas es lo que se necesita y es más simple de implementar y entender. (Herencia ya me parece que es algo asociado a OO, GeneXus va por otro camino/paradigma).

    ResponderEliminar
  5. Buena propuesta.
    Una extension de los Styles seria un buen camino, donde se toman los eventos/rules/propiedades del style para todos los eventos/rules/propiedades que en el objeto tenga el valor default.

    Puede mejorar bastante a que la aplicacion sea mas mantenible.

    ResponderEliminar
  6. Si, diría que debería ser extendido a algo más que los objetos Style, los mismos Style podrían ser "Extensiones" de otros Styles.
    Yo tomaría a los Styles como "objetos no generables/ejecutables" e incorporaría la nueva funcionalidad para todos los objetos GeneXus.

    Bueno, no conozco que tanto uno se puede meter dentro del IDE como para modificar el comportamiento de los componentes (Variables, Printblock's,Editor...).

    Queda ver que opinan de parte de la gente de Artech.

    ResponderEliminar
  7. Supongo que un de los problemas de implementación de la herencia es como implementarla en cada uno de los generadores.
    La propuesta de David tiene la ventaja que se puede implementar antes de la generación, o sea en forma independiente del lenguaje. Igual me gusta más una herencia "posta" (que capaz que en una de esas se puede implementar a nivel de la especificación)
    Otra posibilidad es implementar composición e interfaces. Con esas herramientas no solo se cubre la casuistica de herencia si no muchos otros casos. Aunque habria que tener en cuenta la curva de apredizaje. Usar composición es trivial, pero usarla para una herencia no es tan intuitivo (aunque es sencillo)

    ResponderEliminar
  8. el Kave: Pienso que si se implementara herencia, se podría hacer tanto a nivel del lenguaje generado, como a nivel del especificador/generador.

    Con respecto a hacerlo en el lenguaje generado, cualquiera de los soportados en serio (Java, C# y Ruby) tienen herencia, así que por ahí no veo que hubiera problema.

    Si se hace en el especificador, los programas generados quedarían con código repetido, pero eso no me preocupa, porque se mantienen automáticamente.

    En conclusión, me parece bien cualquiera de las dos alternativas.

    Con respecto a los templates, me parece que habría que definir bien el alcance. En principio debería alcanzar para lo que pretendía en esta nota...

    ResponderEliminar
  9. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  10. Hola a todos, me permito hacer un intento por revivir este post... a ver si tengo éxito.
    Hace poco tuvimos una propuesta de proyecto, pero una de las condiciones era que el lenguaje de programación se adapte al modelo MVC, así fue que empecé a investigar cómo se podía lograr esto con GeneXus, y también conducirlo hacia las bondades de la OO.
    Los invito a compartir sus experiencias, ya que este thread data del 2010 y pasaron ya 2 años.
    Desde ya, muchas gracias.

    Geraldo M. Escobar
    Analista Senior Gx Ev1
    Corrientes, Arg

    ResponderEliminar