<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : Generaci&amp;#243;n de C&amp;#243;digo, Java</title><link>http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/Java/default.aspx</link><description>Tags: Generaci&amp;#243;n de C&amp;#243;digo, Java</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Ejecutando AjGenesis usando Mono y Ubuntu</title><link>http://msmvps.com/blogs/lopez/archive/2010/10/15/ejecutando-ajgenesis-usando-mono-y-ubuntu.aspx</link><pubDate>Fri, 15 Oct 2010 10:01:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1780010</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1780010</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/10/15/ejecutando-ajgenesis-usando-mono-y-ubuntu.aspx#comments</comments><description>&lt;p&gt;En estos días, estoy trabajando en el desarrollo de una nueva versión (reescritura completa) de una aplicación Java, con una interfaz web. Es un trabajo de equipo, donde la mayoría de los integrantes son fans de Ubunto: son más productivos trabajando en Linux. El proyecto tiene generación de código, usando (… jeje.. adivinien… ;-) &lt;a href="http://ajgenesis.codeplex.com" target="_blank"&gt;AjGenesis&lt;/a&gt;, mi proyecto de código abierto, que genera el código y texto que nosotros necesitamos. Ahora, el equipo quiere ejecutar AjGenesis pero no en Windows.&lt;/p&gt;  &lt;p&gt;AjGenesis está escrito en VB.NET, y compilado para .NET 2.0. Yo temía que tuviera que hacer cambios para ejecutarlo bajo &lt;a href="http://www.ubuntu.com/" target="_blank"&gt;Ubuntu&lt;/a&gt; usando &lt;a href="http://www.mono-project.com" target="_blank"&gt;Mono project&lt;/a&gt;. Pero estaba equivocado. Ubunto tiene Mono pre-instalado. Pero AjGenesis usa el runtime de VB.NET. Bien, Mono tiene&lt;a href="http://www.mono-project.com/VisualBasic.NET_support" target="_blank"&gt; VB.NET compiler&lt;/a&gt;. Lancé la terminal en mi Ubunto (albergado en &lt;a href="http://www.virtualbox.org/" target="_blank"&gt;Virtual Box&lt;/a&gt; con host Windows 2008), y ejecuté:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;sudo apt-get install mono-vbnc&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;(Imagino que este paso es necesario, pero debería tratar de ejecutar AjGenesis con sólo Mono instalado. El bueno de &lt;a href="http://twitter.com/MartinSalias" target="_blank"&gt;@MartinSalias&lt;/a&gt; me avisa que ejecuta en MacOS sin bajar nada).&lt;/p&gt;  &lt;p&gt;Después, bajé los &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/AjGenesis/AjGenesisTrunkBinaries.zip" target="_blank"&gt;compilados binarios de AjGenesis&lt;/a&gt; (compilados desde el trunk). Y bajé algunos ejemplos, comoe &lt;a href="http://www.ajlopez.com/downloads/AppExampleStep06.zip" target="_blank"&gt;AppExampleStep06.zip&lt;/a&gt; (descripto en &lt;a href="http://ajlopez.wordpress.com/2010/10/04/building-an-application-using-ajgenesis-part-6/" target="_blank"&gt;Building an Application using AjGenesis (Part 6)&lt;/a&gt;) (&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/10/07/armando-una-aplicaci-243-n-usando-ajgenesis-parte-6.aspx" target="_blank"&gt;Armando una Aplicación usando AjGenesis (Part 6)&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;Puedo ejecutar AjGenesis.Console.exe usando&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;mono AjGenesis.Console.exe&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Luego, marqué el .exe como ejecutable:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;chmod +xr- AjGenesis.Console.exe&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;y ahora, puedo ejecutarlo directamente:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ajgenesisubuntu01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;El directorio Build fue creado! Notable!&lt;/p&gt;  &lt;p&gt;Luego de este experimento, tomé el código del proyecto usando subversion, y ejecuté el script de generación de código. El único problema fue una de las tareas, escritas en AjBasic, que estaba creando directorios en minúsculas y luego usándolos con letras en mayúsculas. Arreglé ese error, y ahroa, la generación de código está corriendo. Los miembros del equipo podrán desarrollar tanto en Windows como en Ubunto, usando Java, Tomcat, Maven, y AjGenesis.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1780010" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ubuntu/default.aspx">Ubuntu</category></item><item><title>Generación de código, AjGenesis, y Dunga dunga a la tecnología</title><link>http://msmvps.com/blogs/lopez/archive/2009/06/14/generaci-243-n-de-c-243-digo-ajgenesis-y-dunga-dunga-a-la-tecnolog-237-a.aspx</link><pubDate>Sun, 14 Jun 2009 17:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1695333</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1695333</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/06/14/generaci-243-n-de-c-243-digo-ajgenesis-y-dunga-dunga-a-la-tecnolog-237-a.aspx#comments</comments><description>&lt;p&gt;En un post m&amp;iacute;o&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/08/02/sobre-la-generaci-243-n-de-c-243-digo.aspx"&gt;Sobre la generaci&amp;oacute;n de c&amp;oacute;digo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;comentaba sobre &lt;a target="_blank" href="http://ajgenesis.codeplex.com"&gt;AjGenesis&lt;/a&gt; y generaci&amp;oacute;n de c&amp;oacute;digo en general. En uno de los p&amp;aacute;rrafos declaraba:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h5&gt;Dunga dunga un ratito&lt;/h5&gt;
&lt;p&gt;De alguna forma, un generador de c&amp;oacute;digo ideal no estar&amp;aacute; atado a una tecnolog&amp;iacute;a. Siempre habr&amp;aacute; alguna &amp;quot;better mousetrap&amp;quot;, siempre alguien inventar&amp;aacute; alguna nueva forma de hacer algo, siempre habr&amp;aacute; un ruso con insomnio, o un hind&amp;uacute; sin novia, que no tiene otra cosa que hacer que crear algo nuevo, ya sea en forma de librer&amp;iacute;a, framework, patr&amp;oacute;n, o estilo arquitect&amp;oacute;nico. Un generador de c&amp;oacute;digo debe ser agn&amp;oacute;stico de la tecnolog&amp;iacute;a, de las modas, de las soluciones actuales y futuras.&lt;/p&gt;
&lt;p&gt;El generador de c&amp;oacute;digo que adoptemos, debe poder adaptarse a lo que queramos hoy y ma&amp;ntilde;ana y pasado ma&amp;ntilde;ana. La estrategia es: no importa la tecnolog&amp;iacute;a, el patr&amp;oacute;n o el framework que aparezca, nuestro generador deber&amp;aacute; aprovecharse de lo que surja. Es lo que llamo la estrategia &amp;quot;dunga dunga&amp;quot;: si aparece una nueva tecnolog&amp;iacute;a T1, le hacemos &amp;quot;dunga dunga&amp;quot; a T1, si aparece un nuevo framework PiruloStruts, adaptamos nuestras plantillas a aprovecharse de ese framework, &amp;quot;dunga dunga&amp;quot; a PiruloStruts. Es como un maestro de aikido: siempre habr&amp;aacute; alguien m&amp;aacute;s fuerte, s&amp;oacute;lo hay que utilizar la fuerza del otro, para vencerlo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un comentador &lt;a href="http://emmanueloga.blogspot.com"&gt;Emmanuel&lt;/a&gt; escrib&amp;iacute;a:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Un resumen y secciones mas especificas ayudar&amp;iacute;an (tienes que admitir que &amp;quot;Dunga dunga un ratito&amp;quot; es un titulo sobre el cual es dif&amp;igrave;cil sacar conclusiones :).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bien, me refer&amp;iacute;a a un viejo chiste, que no encontr&amp;eacute; ahora en la web, as&amp;iacute; que tratar&amp;eacute; de transcribirlo aqu&amp;iacute;, como pueda: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Resulta que un explorador se pierde en la selva, y ya exhausto, se encuentra con una tribu de ind&amp;iacute;genas, con caras de pocos amigos. Lo rodean, el que parece el jefe, se le acerca, y le despacha:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Hombre blanco! Elige! Dunga dunga o muerte!!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;El explorador no entiende qu&amp;eacute; es eso de &amp;ldquo;dunga dunga&amp;rdquo;, as&amp;iacute; que acepta eso, antes que la muerte. Los miembros de la tribu sonr&amp;iacute;en, y le empiezan a dar al pobre explorador, de formas que &amp;eacute;ste no se lo imaginaba&amp;hellip; &lt;/p&gt;
&lt;p&gt;Lo dejan, y el explorador, maltrecho, sigue su camino, se encuentra con otra tribu, otro jefe, y la ya cl&amp;aacute;sica frase:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Hombre blanco! Elige! Dunga dunga o muerte!!&amp;rdquo;&lt;/p&gt;
&lt;p&gt;El explorador, escarmentado, responde:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;No!! No dunga dunga de nuevo!! no!!! Prefiero la muerte!!&amp;rdquo;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;El jefe asiente, pero se le acerca, le pasa brazo por el hombre, y con afecto y sonriendo, le dice:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Bueno, muerte, pero antes&amp;hellip; dunga dunga un ratito, eh?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;:-) :-)&lt;/p&gt;
&lt;p&gt;A eso me refer&amp;iacute;a cuando escrib&amp;iacute; ese post. AjGenesis, como generador de c&amp;oacute;digo, no est&amp;aacute; especializado en producir artefactos para una tecnolog&amp;iacute;a. No es como Xdoclet que s&amp;oacute;lo produce Java, o est&amp;aacute; muy orientado (por lo menos en sus comienzos) a EJB (Enterprise Java Beans).&lt;/p&gt;
&lt;p&gt;No, lo que hace AjGenesis, es aprovecharse del conocimiento del programador o equipo de programaci&amp;oacute;n, de las tecnolog&amp;iacute;as, frameworks existentes o futuros, y generar gran parte de una soluci&amp;oacute;n (o por lo menos la parte repetitiva).&lt;/p&gt;
&lt;p&gt;Recordemos que AjGenesis puede partir de un modelo abstracto y generar artefactos de textos (que pueden ser una soluci&amp;oacute;n completa):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgenesis30.png" alt="" /&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Notemos que puede haber m&amp;aacute;s de un modelo inicial. En muchos de los ejemplos que publiqu&amp;eacute;, hay un modelo independiente de la plataforma (por ejemplo, que describe que nuestro sistemas tendr&amp;aacute; departamentos, empleados, clientes, proveedores&amp;hellip;) y un modelo de tecnolog&amp;iacute;a (que indica que vamos a usar tal base de datos, y tal lenguaje, y una interface web, etc..)&lt;/p&gt;
&lt;p&gt;Pero tambi&amp;eacute;n puede partir de la base de datos, y generar un modelo de base, que puede ser completado, ajustado, y usado m&amp;aacute;s adelante la generaci&amp;oacute;n de c&amp;oacute;digo:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgenesis31.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;El modelo a usar es totalmente definible. Y las tareas y plantillas a usar, totalmente definibles. Si lo que Uds. necesitan, es generar aplicaciones con interfaz web, usando Struts 2, es cuesti&amp;oacute;n de armarse las plantillas y tareas que generen ese tipo de soluci&amp;oacute;n. Si luego necesitan generar una aplicaci&amp;oacute;n en ASP.NET 3.5, con persistencia resuelta en NHibernate, de nuevo es cuesti&amp;oacute;n de definir las tareas y plantillas adecuadas.&lt;/p&gt;
&lt;p&gt;Pero si el d&amp;iacute;a de ma&amp;ntilde;ana, aparece un nuevo ORM (Object Relational Mapper), o hay una nueva forma de implementar la persistencia, podemos &amp;ldquo;instruir&amp;rdquo; al AjGenesis para que genere los artefactos de textos que necesitemos.&lt;/p&gt;
&lt;p&gt;Ya he publicado ejemplos, explicaciones de todo esto en&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx"&gt;Posts sobre AjGenesis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;desde una explicaci&amp;oacute;n de Hola Mundo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx" title="Generando C&amp;oacute;digo- Hello World con AjGenesis"&gt;Generando C&amp;oacute;digo- Hello World con AjGenesis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;hasta aplicaciones completas en distintas tecnolog&amp;iacute;as:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/06/25/generando-aplicaciones-con-ajgenesis.aspx" title="Generando aplicaciones con AjGenesis"&gt;Generando aplicaciones con AjGenesis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En esos ejemplos, el modelo se define en archivos XML, pero tambi&amp;eacute;n pueden tomarlo desde texto:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/09/29/modelo-textual-para-generaci-243-n-de-c-243-digo-con-ajgenesis.aspx" title="Modelo textual para generaci&amp;oacute;n de c&amp;oacute;digo con AjGenesis"&gt;Modelo textual para generaci&amp;oacute;n de c&amp;oacute;digo con AjGenesis&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;y desde otras fuentes menos convencionales:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/11/25/ajgenesis-modelo-desde-la-base-de-datos.aspx" title="AjGenesis- Modelo desde la Base de Datos"&gt;AjGenesis- Modelo desde la Base de Datos&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/11/27/ajgenesis-modelo-generado-desde-los-assemblies.aspx" title="AjGenesis- Modelo generado desde los assemblies"&gt;AjGenesis- Modelo generado desde los assemblies&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si hasta pueden implementar una soluci&amp;oacute;n web que genere c&amp;oacute;digo para cualquiera que lo necesite:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/04/03/code-generation-as-a-service.aspx" title="Code Generation as a Service"&gt;Code Generation as a Service&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As&amp;iacute; que no tienen excusas: no pueden quejarse de que no les avis&amp;eacute;, o que me encanut&amp;eacute;, ocult&amp;eacute; algo bajo la manga. Tienen todo eso disponible desde hace a&amp;ntilde;os. S&amp;oacute;lo falta poner cabeza y cerebro, en descubrir los modelos de base que necesitamos, y escribir las tareas y plantillas. Recomiendo siempre partir de una aplicaci&amp;oacute;n de ejemplo, que resuelva lo que Uds. necesitan, usando la tecnolog&amp;iacute;a que hayan elegido, y desde ah&amp;iacute;, ir construyendo las tareas y plantillas que necesiten.&lt;/p&gt;
&lt;p&gt;Como siempre aclaro, no toda la aplicaci&amp;oacute;n puede crearse por generaci&amp;oacute;n de c&amp;oacute;digo. Pero se pueden aplicar t&amp;eacute;cnicas, como generar desde el modelo que elijamos, s&amp;oacute;lo algunos artefactos de texto, y otros, los generamos manualmente.&lt;/p&gt;
&lt;p&gt;Lo interesante, es que as&amp;iacute;, cuando pasen las tecnolog&amp;iacute;as, cuando aparecen nuevas, podemos reaprovechar nuestro conocimiento anterior, al haber definido un modelo que describa nuestro problema, y luego, al conocer una nueva tecnolog&amp;iacute;a, y c&amp;oacute;mo resolver los mismos problemas de otra forma, podemos generar c&amp;oacute;digo para la nueva forma de hacer las cosas.&lt;/p&gt;
&lt;p&gt;Yendo a un ejemplo concreto. Desde hace d&amp;eacute;cadas, estamos haciendo ABM (Altas, Bajas y Modificaciones) de valores, como pa&amp;iacute;ses, provincias y dem&amp;aacute;s. Cuando resolvimos eso en Visual Fox, un cliente nos pidi&amp;oacute; hacerlo en ASP cl&amp;aacute;sico. Cuando resolvimos eso en ASP cl&amp;aacute;sico, otro cliente nos pidi&amp;oacute; eso en ASP.NET, o en JSP o en JSF (JavaServer Faces) o en lo que aparezca ma&amp;ntilde;ana. Pero el problema a resolver es el mismo: mantener una lista de valores. Si luego cambia la tecnolog&amp;iacute;a, cambia la soluci&amp;oacute;n a aplicar, pero el problema inicial se mantiene. En AjGenesis, podemos definir un modelo independiente&amp;nbsp; de la tecnolog&amp;iacute;a (por ejemplo, definiendo las entidades que tenemos que manejar, como Cliente, Factura, Remito, etc&amp;hellip; y sus relaciones), y por otro, instruyendo sobre qu&amp;eacute; tecnolog&amp;iacute;a usar (aportando uno o varios modelos dependientes de la tecnolog&amp;iacute;a), como ASP.NET, ASP.NET MVC, WCF, JSP, JSF, Struts 1 o 2, etc&amp;hellip;&lt;/p&gt;
&lt;p&gt;Otro camino hubiera sido lo que muchos de nosotros encaramos: hacer nuestro propio framework. He visto muchas consultoras de software, &amp;ldquo;casarse&amp;rdquo; con una tecnolog&amp;iacute;a (ej. Visual Fox), estudiarla, armar un framework sobre ella (que resuelva los problemas cl&amp;aacute;sicos, como ABMs, seguridad, autorizaci&amp;oacute;n, validaciones, etc&amp;hellip;) y luego ver c&amp;oacute;mo, ese trabajo de a&amp;ntilde;os, se diluye, porque la tecnolog&amp;iacute;a cambia.&lt;/p&gt;
&lt;p&gt;Si nosotros elevamos el nivel de abstracci&amp;oacute;n, identificamos los problemas a resolver (ABMs, listas, buscadores, seguridad, procesos, validaciones, reglas de negocio), y luego los resolvemos en una tecnolog&amp;iacute;a (ya sea viendo c&amp;oacute;digo de ejemplo, armando nuestros propios ejemplos, et&amp;hellip;), podemos describir ese mapeo de problema a soluci&amp;oacute;n concreta, usando las tareas y plantillas de AjGenesis.&lt;/p&gt;
&lt;p&gt;Como ejemplo: cuando comenc&amp;eacute; con el proyecto, no exist&amp;iacute;a ASP.NET 2.x. Sin embargo, los modelos que constru&amp;iacute; como ejemplos de base, pudieron ser usados para luego generar aplicaciones de ASP.NET 2.x. Actualmente, en un proyecto, estamos adaptando conocimiento previo, para generar c&amp;oacute;digo sobre .NET y &lt;a target="_blank" href="http://www.oakleafsd.com/pgProducts_mmnet.htm"&gt;Mere Mortals Framework&lt;/a&gt;. Y el modelo que construimos, f&amp;aacute;cilmente podr&amp;iacute;a ser reusado para otras aplicaciones, y otras tecnolog&amp;iacute;as,como Clipper o COBOL, hasta ASP.NET MVC o Wicket. El construir el modelo, pone de manifiesto qu&amp;eacute; es lo que queremos resolver, los problemas b&amp;aacute;sicos, que terminan expres&amp;aacute;ndose de forma independiente de la tecnolog&amp;iacute;a de moda, o el framework popular del momento.&lt;/p&gt;
&lt;p&gt;Y aunque usemos una sola tecnolog&amp;iacute;a, el ejercicio de definir el modelo, definir las tareas y plantillas, aporta una clara separaci&amp;oacute;n entre lo abstracto, y lo que llamo las &amp;ldquo;technicalities&amp;rdquo;, los detalles t&amp;eacute;cnicos de implementaci&amp;oacute;n, que el d&amp;iacute;a de ma&amp;ntilde;ana pueden cambiar.&lt;/p&gt;
&lt;p&gt;Entonces, no importa la tecnolog&amp;iacute;a: AjGenesis le puede hacer dunga dunga a la tecnolog&amp;iacute;a que venga. Si Uds. creen que la tecnolog&amp;iacute;a que Uds. usan actualmente, va a durar para siempre, lamento desilusionarlos. Vean la historia de la programaci&amp;oacute;n, los &amp;uacute;ltimos 30 o 50 a&amp;ntilde;os, y ver&amp;aacute;n que lo &amp;uacute;nico permanente es el cambio.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt; &lt;br /&gt;&lt;a href="http://www.facebook.com/ajlopez" title="http://www.facebook.com/ajlopez"&gt;http://www.facebook.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1695333" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Charla gratuita sobre generación de código</title><link>http://msmvps.com/blogs/lopez/archive/2008/06/06/charla-gratuita-sobre-generaci-243-n-de-c-243-digo.aspx</link><pubDate>Fri, 06 Jun 2008 13:48:42 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1632327</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1632327</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/06/06/charla-gratuita-sobre-generaci-243-n-de-c-243-digo.aspx#comments</comments><description>&lt;p&gt;Casi todos los cursos y charlas que doy, termino mencionando generación de código, desde un modelo, como una solución pragmática a varios problemas que tenemos al desarrollar sistemas. El lunes que viene, doy una charla gratuita sobre el tema, en el &lt;a href="http://www.clubdeprogramadores.com" target="_blank"&gt;Club de Programadores&lt;/a&gt;, acá en Buenos Aires.&lt;/p&gt; &lt;p&gt;Más información e inscripción:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.clubdeprogramadores.com/cursos/CursoMuestra.php?Id=439" target="_blank"&gt;Curso Generacion de Código&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Objetivos&lt;/strong&gt;&lt;br /&gt;Durante la charla, examineremos el concepto de modelo independiente de la plataforma de un sistema, y mediante tecnologias de templates, generaremos codigo para gran parte de una aplicacion, en distintas tecnologias, como PHP, Java con JSP, .NET con ASP.NET, contra MySql o SQL Server, usando distintas estrategias de persistencia, como procedimientos almacenados o NHibernate. Todo basado en un mismo modelo, con distintas plantillas de generacion de codigo, manejados desde el proyecto de codigo abierto &lt;a href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;.  &lt;p&gt;&lt;strong&gt;Plan de Estudio&lt;/strong&gt;&lt;br /&gt;- Modelo independiente de la plataforma&lt;br /&gt;- Generacion de artefactos de texto con logica y plantillas definibles por cada usuario (no produce algo fijo, sino codigo como el que hubiéramos producido en nuestro equipo de programacion)&lt;br /&gt;- Capacidad de ejecutar varias tareas adicionales (compilacion, instalacion en la base, ....)&lt;br /&gt;- Organizacion de esa tareas de generacion y adicionales en forma automatica y repetible&lt;br /&gt;- Adaptacion a varias tecnologias destino  &lt;p&gt;Lo mío es un apostolado, espero que puedan &amp;quot;ver la luz&amp;quot; .... :-) ;-) &lt;p&gt;Hay bastante sobre el tema publicado en este blog en: &lt;p&gt;&lt;a title="AjGenesis" href="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx"&gt;AjGenesis&lt;/a&gt;&lt;br /&gt;&lt;a title="Generaci&amp;oacute;n de C&amp;oacute;digo" href="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx"&gt;Generación de Código&lt;/a&gt; &lt;p&gt;Artículo inicial a leer  &lt;p&gt;&lt;a title="Sobre la generaci&amp;oacute;n de c&amp;oacute;digo" href="http://msmvps.com/blogs/lopez/archive/2007/08/02/sobre-la-generaci-243-n-de-c-243-digo.aspx"&gt;Sobre la generación de código&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Algunos enlaces a recursos en la web: &lt;p&gt;&lt;a href="http://del.icio.us/ajlopez/codegeneration"&gt;http://del.icio.us/ajlopez/codegeneration&lt;/a&gt; &lt;p&gt;Nos leemos! &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1632327" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/PHP/default.aspx">PHP</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Reunión de Generación de Sistemas con AjGenesis</title><link>http://msmvps.com/blogs/lopez/archive/2007/09/03/reuni-243-n-de-generaci-243-n-de-sistemas-con-ajgenesis.aspx</link><pubDate>Mon, 03 Sep 2007 11:16:33 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1160666</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1160666</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2007/09/03/reuni-243-n-de-generaci-243-n-de-sistemas-con-ajgenesis.aspx#comments</comments><description>&lt;p&gt;Ya había anunciado que el viernes pasado había &lt;a href="http://msmvps.com/blogs/lopez/archive/2007/08/16/desayuno-de-arquitectura-con-ajgenesis.aspx" target="_blank"&gt;desayuno de arquitectura&lt;/a&gt;, en el &lt;a href="http://www.mug.org.ar/"&gt;Microsoft User Group de Argentina&lt;/a&gt;. Agradezco desde acá a la gente del MUG por haberme dado la oportunidad de presentar este proyecto, y las ideas que me llevaron a implementarlo.&lt;/p&gt; &lt;p&gt;La reunión comenzó a las 9 horas y monedas, y seguimos casi hasta las 12hs, hubo charla informal post reunión, muy interesante.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.ajlopez.net/ReferenciaVe.php?Id=209"&gt;Material del Desayuno de Arquitectura sobre AjGenesis&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Para los que no conozcan sobre &lt;a href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;, mi &amp;quot;pet project&amp;quot; de generación de código, leer alguno de los &amp;quot;post&amp;quot;:&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/06/25/generando-aplicaciones-con-ajgenesis.aspx"&gt;Generación de aplicaciones con AjGenesis&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx"&gt;Generando código: Hello World con AjGenesis&lt;/a&gt;  &lt;h3&gt;Presentación&lt;/h3&gt; &lt;p&gt;Pueden bajarse del material de la reunión, la presentación que usé, ya usada en una reunión del año pasado. Esta vez, usé los primeros puntos de esa presentación, y varios de los puntos ya escritos en&lt;/p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2007/08/02/sobre-la-generaci-243-n-de-c-243-digo.aspx"&gt;Sobre la generación de código&lt;/a&gt;&lt;br /&gt; &lt;p&gt;Así que acá agregaré algunos puntos adicionales, que no había pasado por escrito:&lt;/p&gt; &lt;p&gt;. &lt;strong&gt;La adopción de una variante del AjBasic como lenguaje de templates&lt;/strong&gt;: motivada por la necesidad de tener un lenguaje de programación, no solamente una forma de expandir variables dentro de un template, o ejecutar algún for each sobre una lista de objetos del modelo. Creo que fue una buena elección, y siempre queda abierta la posibilidad de usar otro lenguaje para los templates. Con AjBasic tengo la posibilidad de tratar el modelo como un grafo de objetos (no solo como un árbol, como sería si trabajara con XML solamente), modificable, competable (puedo tomar decisiones y agregar elementos al modelo). Pequeñas cosas como&lt;/p&gt; &lt;p&gt;&lt;font face="Consolas" size="3"&gt;if not Project.Title then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Project.Title = Project.Name&lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas" size="3"&gt;end if&lt;/font&gt;&lt;/p&gt; &lt;p&gt;o compleciones del modelo como&lt;/p&gt;&lt;font face="Consolas" size="3"&gt;if Entity.Reference then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Entity.Reference = GetEntity(Entity.Reference)&lt;br /&gt;&lt;/font&gt;&lt;font face="Consolas" size="3"&gt;end if&lt;/font&gt;  &lt;p&gt;(donde Entity.Reference inicialmente tiene solo el NOMBRE de la entidad referida, y luego lo reemplazo por la entidad completa, para armar un grafo de objetos, desde un árbol inicial de objetos).&lt;/p&gt; &lt;p&gt;son posibles al haber elegido ese camino.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;El modelo libre&lt;/strong&gt;:&amp;nbsp;mostré el ejemplo del Hello World, y cómo desde ese modelo se puede generar código o artefactos de texto, llamada desde consola, la ejecución de pequeñas tareas en AjBasic, y la integración con NAnt.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Ejemplos de modelos y templates&lt;/strong&gt;: me basé en lo que ya estaba escrito en &lt;a href="http://www.ajlopez.com/downloads/AjGenesisExamples3.zip"&gt;AjGenesisExamples3.zip&lt;/a&gt; y &lt;a href="http://msmvps.com/blogs/lopez/archive/2007/06/25/generando-aplicaciones-con-ajgenesis.aspx"&gt;Generación de aplicaciones con AjGenesis&lt;/a&gt; donde se muestra un ejemplo. No es que AjGenesis se base sobre &amp;quot;ese modelo&amp;quot;, sólo son ejemplos de distintos proyectos, sobre el mismo modelo, que se concentra en representar entidades, y templates que generan Java, Java con Hibernate, VB.NET 1/2, CSharp 1/2, business entities, o implementaciones con conceptos de Domain-Driven Desing.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Uso de XML para describir el modelo&lt;/strong&gt;: usando un XML libre, no sujeto a un esquema, que no &amp;quot;duela los ojos&amp;quot; leerlo, nos permite ir agregando elementos al modelo, sin tener que modificar una base de datos, o cambiando un esquema con el que hay que cumplir a rajatabla. Creo que ha sido una decisión que ha permitido que cada uno experimente con distintos modelos, rápidamente. Más sobre el tema más adelante en este post.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Prototipos y semillas&lt;/strong&gt;: mostré cómo el AjGenesis puede generar sus propios modelos, desde modelos más sencillos. El ejemplo, basado en el modelo de AjGenesisExamples2/3, pasa, de una simple lista de entidades, cada una prototípica de alguna categoría (&amp;quot;kantiana&amp;quot; la llamé ;-) como persona, documento, lugar, empresa, evento, a un modelo más completo, con armado del directorio del proyecto, el archivo que lo describe, los archivos de entidades, los archivos de tecnología, y los scripts del NAnt, listos para usar.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Caminos a encarar&lt;/strong&gt;: como una aplicación web que permita exponer los servicios de AjGenesis, el uso de inteligencia artifical, pasar a un modelo ASP (Application Service Provider), integración con IDEs (por ejemplo, un custom tool para Visual Studio 2005, o un plugin para el Eclipse).&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;CodePlex&lt;/strong&gt;: Ahora el proyecto está en &lt;a href="http://www.codeplex.com/ajgenesis" target="_blank"&gt;Codeplex&lt;/a&gt; y ahi tenemos un foro para plantear dudas, discusiones y problemas encontrados.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Version 0.5&lt;/strong&gt;: En desarrollo, apenas comienza su ciclo, pueden encontrarla en &lt;a href="http://www.ajlopez.com/downloads/AjGenesis-0.5.zip" target="_blank"&gt;AjGenesis-0.5.zip&lt;/a&gt;, está armada para .NET 2.x. Todavía tengo que incluir los créditos, a Marcelo Fassi y su compañero Fabián, por el código para soportar comentarios en el modelo XML, soporte de acentos en los templates. De mi parte, el mayor cambio ha sido recompilarlo a .NET 2.x, pero este fin de semana, agregué el soporte de respetar código manual (escrito por el programador) entre una y otra generación del artefacto de texto. Espero bloguear en estos días, sobre estas novedades.&lt;/p&gt; &lt;h3&gt;Discusión&lt;/h3&gt; &lt;p&gt;Durante la charla, se plantearon varios temas, entre los asistentes. Tuve la alegría de conocer en persona a Fabio Maulo, activo colaborador del proyecto &lt;a href="http://www.hibernate.org/343.html" target="_blank"&gt;NHibernate&lt;/a&gt;, al que conocía de la lista &lt;a href="http://groups-beta.google.com/group/NHibernate-Hispano" target="_blank"&gt;nhibernate-hispano&lt;/a&gt;, administrada por él y &lt;a href="http://darionet.wordpress.com/" target="_blank"&gt;Darío Quintana&lt;/a&gt;. Ya estámoslo convenciendo para que dé una charla magistral sobre NHibernate en el MUG.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Manual&lt;/strong&gt;: fue un tema pedido, la necesidad de tener un manual. Hasta ahora, están los artículos mencionados al principio de este post, para ir entendiendo algunos puntos. Pero es necesario tener un manual, por ejemplo, del lenguaje AjBasic, o que explique algunos usos de las tareas de los ejemplos. Tengo un sistema de documentación en HTML, inspirado en el &lt;a href="http://www.docbook.org/" target="_blank"&gt;DocBook&lt;/a&gt; (dado un formato inicial, generar la documentación), pero sólo escritas cinco páginas. Tácticamente, para suplir esta falta, voy escribiendo artículos sobre el uso del sistema. Carlos Peix sugirió usar la implementación de la gente de &lt;a href="http://velocity.apache.org/" target="_blank"&gt;Velocity&lt;/a&gt;: parece una interesante implementación sobre DocBook.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Lista de Generación de Código&lt;/strong&gt;: Me alegró ver a Luis Petek, Carlos Santos, y Alejandro Nelis, munidos de sus respectivas notebooks, trabajando con templates y generando código con AjGenesis, y estudiando el tema. Armaron una lista donde se discuten estos temas, no sólo de AjGenesis, en Google Groups:&lt;/p&gt; &lt;p&gt;&lt;a href="http://groups.google.com/group/codegeneration?hl=es"&gt;http://groups.google.com/group/codegeneration?hl=es&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Tienen armado un template para SQL Server 2005, y otro con persistencia usando Enterprise Library. Notable, muchas gracias!&lt;/p&gt; &lt;p&gt;Ellos plantearon el tema de tener un repositorio de templates. Siempre pienso en ese, en especial viendo a otros generadores de código. Pero no pensé que hiciera falta todavía. Pero voy viendo que puede ser la hora de exponer algo. Otro tema a meditar, para elegir un camino.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Esquema en modelo&lt;/strong&gt;: Fabio Maulo dejó un comentario muy amable en el post &lt;a href="http://msmvps.com/blogs/lopez/archive/2007/08/16/desayuno-de-arquitectura-con-ajgenesis.aspx" target="_blank"&gt;Desayuno de Arquitectura con AjGenesis&lt;/a&gt;. Reproduzco su tema planteado acá:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;XSD? &lt;p&gt;Me parece que el tema de &amp;quot;XSD o no&amp;quot; entra poco en los objetivos de AjG. Como mucho, AjG puede tener un servicio mas que es lo de aceptar unos XSD (o el nombre del folder donde estan disponible) y chekear los XMLs ante de empezar a aplicarle los templates. Mas que eso a AjG no le veo. &lt;p&gt;Despues de la Genesis sea los animales que los hombres se organizaron en sociedades que conviven dandose algunas reglas. Los XSD lo veo como las &amp;quot;reglas&amp;quot; que se da una determinadad comunidad de utilizadores de AjG para compartir &amp;nbsp;XML de un determinado dominio o de una determinada forma de definir el dominio. &lt;p&gt;Distintas comunidades podrán eleguir distintos XSD. Por lo menos creo que eso es lo que va a pasar... &lt;p&gt;Despues es probable que la evolución sea similar a la que hubo con los lenguajes y los IDE. Yo tambien he trabajado con el &amp;quot;vi&amp;quot; pero no es que este muy entusiasmado con eso. &lt;p&gt;Usando XSD tendriamos un control &amp;quot;temprano&amp;quot; mientras escribimos el domain y hasta se podría &amp;nbsp;hacer un plug-ins para varios IDE para escribir los templates... quiero decir que si existe el XSD podríamos usar el IDE para chequear que exista un determinado tag y sobre todo que siga funcionando el intellisense para el lenguaje por el cual estamos escribiendo el template.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Ciertamente, el tema XSD o algún otro esquema, es un tema a meditar. Tengo un &amp;quot;spike&amp;quot; de un esquema expresado en... chan chan... un modelo de AjGenesis... :-). Esto permitiría expresar el esquema del modelo, y además, generar, por ejemplo, páginas web de actualización del modelo. Pero es por ahora sólo una idea.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mantener código manual&lt;/strong&gt;: Se discutió la necesidad de mantener código manual, dentro de una solución, o incluso, dentro del mismo artefacto de texto. En este último caso, ya pude aportar un intento de solución el fin de semana, en la versión 0.5 que mencioné arriba. También se mencionó de mantener lo manual por subclase, o en clases parciales, en el caso de .NET. &lt;a href="http://claudiomeschini.blogspot.com" target="_blank"&gt;Claudio Meschini&lt;/a&gt; comentó sus ideas sobre generar desde el código mismo, y este fin de semana, posteó sobre &lt;a href="http://claudiomeschini.blogspot.com/2007/08/templates-compilados.html" target="_blank"&gt;templates compilados&lt;/a&gt;. Creo que puedo implementar algo así en AjGenesis directamente, pero me parece que se complica incrustrar ciclos en esos textos. Por lo que entendí, Claudio plantea tener un código, compilable, y de ahí obtener el template. Se discutió el tema al terminar la charla, y es interesante. Me recordó lo que hacía en los 80, con mi sistema de generación de código C: a un código que compilaba, le pasaba una macros de editor, para cambiar, por ejemplo &amp;quot;Alta&lt;strong&gt;Cliente&lt;/strong&gt;(&lt;strong&gt;Cliente&lt;/strong&gt; c)&amp;quot; por &amp;quot;Alta&lt;strong&gt;${Entity}&lt;/strong&gt;(&lt;strong&gt;${Entity}&lt;/strong&gt; c)&amp;quot; (me confunde el término template compilado, no sé si entendí bien a Claudio: lo que estoy describiendo, es un código que compila, que luego puede usarse para generar el template genérico). Vean también el proyecto de&amp;nbsp;Claudio&amp;nbsp;&lt;a href="http://claudiomeschini.blogspot.com/2007/08/presentando-quetzal.html" target="_blank"&gt;Quetzal&lt;/a&gt;: si lo tuviera que hacer en Java, apelaría al proyecto &lt;a href="http://velocity.apache.org/anakia/releases/anakia-1.0/" target="_blank"&gt;Anaxia&lt;/a&gt;, dentro de &lt;a href="http://velocity.apache.org/" target="_blank"&gt;Velocity&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Lógica de negocio&lt;/strong&gt;: ¿cómo expresarla en el modelo? Gran tema, discutido en parte en la charla, y en la reunión post charla. Yo creo que hay dos caminos, uno más cercano que otro:&lt;/p&gt; &lt;p&gt;1- Colocar código para un lenguaje, en el propio modelo (algo como&lt;/p&gt; &lt;p&gt;&lt;font face="Consolas"&gt;&amp;lt;Method... &amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;CodeImplementations&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;CodeImplementation Language=&amp;quot;VBNET&amp;quot;&amp;gt;&lt;br /&gt;... codigo VBNET...&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/CodeImplementation&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;CodeImplementation Language=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;... codigo Java ...&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/CodeImplementation&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/CodeImplementations&amp;gt;&lt;br /&gt;&amp;lt;/Method&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;2- Definir más abstractamente la lógica, mediante:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;2a)- Seudo lenguaje, podría ser un AjBasic, y trasladores de ese lenguaje al lenguaje destino&lt;/p&gt; &lt;p&gt;2b)- Modelo en XML, como en los sistemas de Rule Engines, que luego se vuelca al sistema (no sólo lenguaje) destino&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Creo que el camino 1, es el más fácil, y pragmático. Y más aplicable en el caso de tener varios sistemas, pero con un solo lenguaje de implementación, con distintas lógicas de negocio para distintas versiones. Las distintas versiones de lógica, se podrían mantener como una parte variable del modelo: hoy generamos con la lógica A1, y mañana cargamos el modelo con la lógica A2, de manera similar a como se carga hoy en los ejemplos a la tecnología.&lt;/p&gt; &lt;p&gt;El camino 2a, es interesante. Pero tenemos que discutir qué es &amp;quot;la lógica de negocio&amp;quot;. No necesariamente la lógica va a un método, puede ser que influya en el esquema de definición de un workflow, en un XML de definición de ese workflow, y demás. Pero si es código a incrustar, se puede pensar en el 1, y el 2a.&lt;/p&gt; &lt;p&gt;El camino 2b, es más abstracto. Pero hay que tener claro exactamente que le pedimos como capacidad a la implementación de la lógica de negocio.&lt;/p&gt; &lt;p&gt;Claudio Meschini mencionó LOP Lenguajes orientados a programación. Puede estudiar:&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.onboard.jetbrains.com/is1/articles/04/10/lop/index.html" href="http://www.onboard.jetbrains.com/is1/articles/04/10/lop/index.html"&gt;http://www.onboard.jetbrains.com/is1/articles/04/10/lop/index.html&lt;/a&gt;&lt;br /&gt;&lt;a title="Language-Oriented Programming talk with Neal Ford" href="http://www.theserverside.com/news/thread.tss?thread_id=46674"&gt;Language-Oriented Programming talk with Neal Ford&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Generando el modelo&lt;/strong&gt;: Recordé en algún momento, un trabajo del bueno de Darío Quintana:&lt;/p&gt; &lt;p&gt;&lt;a href="http://darionet.wordpress.com/2006/09/05/reflexion-generacion-de-codigo-modelo-para-ajgenesis/" target="_blank"&gt;Reflexión + Generación de Código = Modelo para AjGenesis&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Esa es la idea: generar el modelo pragmáticamente, desde donde sea. Fabio sugirió levantar los .hbm de un NHibernate, y usarlo como parte de modelo. No se me había ocurrido, pero es posible e interesante: debería cargar un XML cualquiera como objeto y permitirlo vivir en el modelo (eso implica una nueva forma de cargar un XML en memoria para AjGenesis: al contrario de lo que hace ahora, deberá distinguir entre atributo y elemento hijo de un nodo, pero es un cambio que puedo hacer sin afectar la forma actual de carga de modelo).&lt;/p&gt; &lt;h3&gt;Conclusión&lt;/h3&gt; &lt;p&gt;Excelente que la gente se haya enganchado en el tema! Creo que, de las ideas y discusiones planteadas, las prioridades serán:&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Manual&lt;/strong&gt;: indispensable para poder explicar el uso del sistema&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Mantenimiento de código manual&lt;/strong&gt;: algo avancé en la nueva versión 0.5&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Comunidad&lt;/strong&gt;: ya se va formando. Creo que no hay que forzar las cosas, e ir viendo de alimentar el grupo de generación de código, y seguir paso a paso.&lt;/p&gt; &lt;p&gt;- &lt;strong&gt;Modelado de lógica de negocio&lt;/strong&gt;: interesantísimo tema, con varios caminos a seguir.&lt;/p&gt; &lt;p&gt;De nuevo, gracias a la gente del MUG por haberme permitido hacer esta reunión. Y a todos los que vinieron, gracias! Espero que les haya servido, para ver alguna alternativa más sobre el fascinante tema de creación de software.&lt;/p&gt; &lt;p&gt;Nos leemos!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1160666" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Arquitectura/default.aspx">Arquitectura</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Sobre la generación de código</title><link>http://msmvps.com/blogs/lopez/archive/2007/08/02/sobre-la-generaci-243-n-de-c-243-digo.aspx</link><pubDate>Thu, 02 Aug 2007 10:26:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1081900</guid><dc:creator>lopez</dc:creator><slash:comments>32</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1081900</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2007/08/02/sobre-la-generaci-243-n-de-c-243-digo.aspx#comments</comments><description>&lt;p&gt;Quisiera hoy tratar un tema, que de alguna manera lo trato en cada momento en que tengo oportunidad. No es un tema esencial, quizás, dentro del desarrollo de código, pero me parece importante tratarlo, por un tema digamos táctico: hoy por hoy, dada la situación de una serie de tecnologías, &amp;quot;frameworks&amp;quot; y estilos arquitectónicos, pienso que es indispensable estar advertido de este tema. Me refiero a la generación de código. Recorramos una introducción, que nos ponga en perspectiva, que nos muestre algunas causas de la situación actual, y que apoyen la necesidad de la generación de código.&lt;/p&gt; &lt;p&gt;Antes alguna aclaración: es un tema que me importa. Déjenme entonces, revolcarme en la explicación, detenerme en ejemplos y aclaraciones, pasar de un tópico a otro, enumerar detalles y volver al tema principal, divertirme con alguna chanza, referirme a alguna experiencia personal olvidable, o ponerme serio en alguna frase. Y si en alguna parte parezco merecer la internación en instituto mental, y el chaleco de fuerza, les recuerdo que hasta ahora, no lastimé a nadie, y estoy tomando la medicación diaria.... ;-)&lt;/p&gt; &lt;p&gt;No sé si podré transmitir todo lo que quiero expresar. Ludwig Wittgenstein escribió, en una introducción a su Tractatus Lógico-Philosophicus, alguna frase como &amp;quot;Lograría su cometido si complaciera aunque sólo sea a un lector que lo comprenda&amp;quot;. Espero no ser tan oscuro como el joven Ludwig, y que algo de lo que escriba se entienda y sirva a alguien.&lt;/p&gt; &lt;p&gt;El tema me importa: espero que se note.&lt;/p&gt; &lt;h3&gt;Todo cambia&lt;/h3&gt; &lt;p&gt;Recuerdo mis primeros pasos en el desarrollo de software. Tuve que desde perforar tarjetas, graboverificar datos, hasta trabajar con ensamblador de un venerable IBM 360, o un RPG que apenas llegaba a RPG II. Decenas de líneas de código en DATA DIVISION fueron escritas en planillas de programación. Tuve que escribir incomprensibles comandos de Job Control Languages, para hacer que el más mínimo programa pudiera ejecutar. Luego aparecieron por aquí, en mi pais, Argentina, los mini computadores, cada uno con su propio sistema operativo, y sus propios lenguajes y herramientas. Solo con los años, dejé las tarjetas perforadas, por un teclado en una máquina personal. Tuve que escribir en varias variantes de COBOL, en Fortran, en Algol, y hasta en APL (algo que no lo deseo a nadie, ni siquiera a un fanático de Haskell). Asistí al despertar del CP/M, su versión en red, un primer IBM PC, un Xenix de Microsoft, y varios compiladores C. Trabajé con Turbo Pascal, con Turbo C, y con un DBase que apenas abría dos tablas a la vez. Apareció un día una Lisa de Apple, así como al tiempo una Mac, algo llamado mouse, Microsoft contesta con Windows, y .... Puedo seguir un par de párrafos más. Lo que quiero transmitir, más que descubrir ante Uds que nací en&amp;nbsp;el milenio pasado, es destacar, llamar la atención sobre un tema: la tecnología cambia. Si alguien piensa que la tecnología que tiene ahora entre manos, será &amp;quot;the ultimate solution&amp;quot;, me temo que tengo que decirle: mentira. Todo cambia. Podemos discutir las razones: la evolución de la tecnología, la innovación que empujan los nuevos jugadores, el avance en los requerimientos de los propios clientes, y demás. Pero la realidad es una: todo cambia.&lt;/p&gt; &lt;h3&gt;La complejidad&lt;/h3&gt; &lt;p&gt;Una vez asentado ese hecho (no una opinión, no una visión relativa, no una teoría, sino un hecho), pasemos a otro. A medida que aparecen nuevas tecnologías, requerimientos (por ejemplo, ya no hay solo ventanas gráficas, tenemos páginas web, otras presentaciones, texto a voz, pequeños dispositivos....), y formas de hacer sistemas, vemos que todo conspira para que cada sistema que encaremos, sea cada vez más complejo, o por lo menos, más largo y grande de construir. Ya es raro encontrar un sistema que pueda desarrollar un programador en solitario: cualquier sistema no trivial implica un equipo de trabajo, y el diseño, creación, ensamble, prueba de multitud de artefactos. Ya no es un simple formulario en Clipper: cada sistema implica parva de elementos a manejar, construir, relacionar.&lt;/p&gt; &lt;p&gt;Podríamos discutir si esto lo llamamos complejidad, o simplemente largura. Pero de alguna forma, Dorothy, ya no estamos más en Kansas: la creación de software, se complicó.&lt;/p&gt; &lt;h3&gt;No somos vulcanos&lt;/h3&gt; &lt;p&gt;¿Recuerdan al Señor Spock, de Viaje&amp;nbsp;a las Estrellas? Como vulcano, podía analizar todo, y manejar ingentes cantidades de información, y seguir con la razón hacia adelante, resolviendo todo problema. No somos vulcanos. Mientras un vulcano, me imagino, puede escribir un sistema completo como un todo, nosotros, como humanos, no podemos &amp;quot;manejar&amp;quot; más de ocho o nueve temas al mismo tiempo. La construcción de software es una actividad humana que implica la mayor cantidad de niveles de detalle: tenemos que ser capaces de ver la arquitectura general del sistema, hasta estar en el detalle del último procedimiento almacenado, o la serialización de un mensaje en forma eficiente para transportar en un servicio web. Esa en la razón de la aparición de arquitectura, patrones y otras soluciones: son soluciones que ayudan a superar nuestras limitaciones humanas. Un sistema con capas o sin capas, es de igual de complejo para un procesador. Es por y para nosotros, los humanos, que los sistemas se organizan, se parten, se analizan y diseñan. Es por nosotros, que la arquitectura de software apela al viejo &amp;quot;divide y vencerás&amp;quot;. Es por nosotros, que tenemos patrones. Es por nosotros, que adoptamos en programación estructurada la abolición del GOTO (noten que cualquier procesador tiene GOTO, y que todo ejecutable, tiene miles de GOTO: la desaparición de esta &amp;quot;infame&amp;quot; construcción ocurrió a nivel humano, a nivel de los lenguajes que manejamos, los procesadores ni se enteraron del problema).&lt;/p&gt; &lt;p&gt;Cada año que pasa, es más evidente que necesitamos ayuda para construcción de software. No podemos solos.&lt;/p&gt; &lt;h3&gt;Software que genera software&lt;/h3&gt; &lt;p&gt;En los ochenta, me comentaron una idea: cuando uno arma una herramienta de software, sería bueno que nos ayude a generar más software. No solamente armar herramientas para otros, sino que de alguna forma, cada esfuerzo que hagamos en armar algo, nos ayude, potencie, las capacidades de seguir haciendo. Esto permite que cada tiempo que invertimos, de alguna forma nos vuelva en provecho a nuestro trabajo, y por otra, ejercitar el &amp;quot;dog fooding&amp;quot;: comer la comida del perro, usar las propias herramientas, para apreciar las ventajas y limitaciones de lo que producimos.&lt;/p&gt; &lt;p&gt;Ese consejo lo comencé a aplicar en mis primeros programas en Lattice C, para PC. Necesitaba escribir rutinas que pasaban de una estructura de datos a un sistema de archivo indexado que había armado en un venerable assembler. No quieran imaginar la cantidad de código que eso implicaba. Luego, necesité pantallas de ingreso de datos, que manejaran el cursor, posicionamiento en una consola de texto, ingreso de campos y demás. Armé una librería de ingreso y manejo de campos. Pero igual cada pantalla era gran cantidad de código. Entonces, recordando el consejo del párrafo anterior, se armó un generador ese código en C. El propio generador estaba escrito en C. Epifanía: la creación de gran parte de un sistema, que era un trabajo tedioso, lleno de probables errores, quedó reducida a minutos.&lt;/p&gt; &lt;p&gt;Algunos de Uds lo habrán experimentado: descubrir algo que nos ayuda enormemente en el trabajo de cada día. Pero ¿cuál era el problema de esa solución? Solo funcionaba para lo que yo necesitaba. Si quería generar otra cosa, tenía que cambiar mucho del código original. Igualmente, con un grupo, pasamos la librería original a Xenix, y notablemente, siguió produciendo código para ese sistema operativo.&lt;/p&gt; &lt;p&gt;Pero la tecnología cambiaba. Llegó un momento, en que era más fácil usar las nuevas IDEs (entornos de desarrollo), que generar el código de esa forma. Pero siempre me quedó en la cabecita, la idea de volver a esa herramienta.&lt;/p&gt; &lt;p&gt;Pero destaquemos algo: la idea de software generando software, no es nueva. Es una idea que aplicamos cada vez que ejecutamos un compilador. Veamos el esquema: escribimos nuestros programas en un lenguaje de nivel más alto que el de la máquina. Pero luego, no vamos pasando de ese lenguaje a binario a mano: no estamos generando los bits (que de eso se compone un ejecuble) manualmente en un archivo. No señor. Apelamos a una herramienta.&lt;/p&gt; &lt;h3&gt;Creando sistemas con tecnologías&lt;/h3&gt; &lt;p&gt;Si Uds. trabajaron muchos años en alguna tecnología (llámese Clipper, Visual Fox, Visual Basic, Java o .NET), habrán llegado al punto de ser &amp;quot;proficient&amp;quot;, de ser capaces de armar sistemas no triviales, manejando sin titubear cada detalle de la tecnología que eligieron. Claro, esa capacidad lleva su tiempo adquirirla. Pero habrán resuelto cómo armar los clásicos ABMs (altas, bajas y modificaciones), accesos a bases de datos, reportes, presentación de menúes, login de usuario y otros. Así hacíamos el sistema S1, luego el S2, y cuando nos encargan el sistema S3, tomamos el S2 como base, y lo vamos cambiando, para no generar el S3 desde el principio.&lt;/p&gt; &lt;p&gt;Eso que hicimos por años se puede resumir:&lt;/p&gt; &lt;p&gt;- Dada una tecnología, la vamos conociendo (aprendiendo cada propiedad de cada control en Visual Basic, o cada método de la API de ADO, DAO, JDBC o lo que nos venga...)&lt;/p&gt; &lt;p&gt;- Dado los sistemas que nos toca construir, vamos solucionando los distintos elementos (cómo acceder a datos, cómo ingresar una entidad, dónde colocar las validaciones...)&lt;/p&gt; &lt;p&gt;- Cuando tenemos un nuevo sistema, nos basamos en lo que ya construímos&lt;/p&gt; &lt;h3&gt;Frameworks y librerías&lt;/h3&gt; &lt;p&gt;Próximo paso que algunos dimos: luego de haber resuelto los puntos del párrafo anterior, se nos ocurre:&lt;/p&gt; &lt;p&gt;- Armar una librería de clases, que resuelvan lo que hacemos repetitivamente en cada sistema&lt;/p&gt; &lt;p&gt;- O adoptamos algún framework, ya sea de Visual Fox, el de Lothka para Visual Basic, ya sea las recomendaciones de Sun para un J2EE, o Struts, o Spring,&amp;nbsp;o cualquier otro, que alguien haya hecho, para solucionar algunos temas que no queremos armar nosotros.&lt;/p&gt; &lt;p&gt;Pero armar una librería de clases es trabajoso. Y cuando finalmente la conseguimos, cambia la tecnología. Ejemplo: durante años, aprendimos cómo trabajar con Visual Fox. Luego, armamos la librería de clases que nos va a solucionar todo lo que hagamos de ahora en más con ese tecnología. Luego, la realidad se ríe, y aparece la web, Java, multiplataforma, .NET y todo lo demás, y nuestra inversión en la librería, bien, pueden imaginar donde podemos ponerla.&lt;/p&gt; &lt;p&gt;No vamos mejor si adoptamos una librería de otra gente. Al principio, la librería parece maravillosa. Pero al tiempo, no soluciona todo. Y cuando cambia la tecnología, resulta que la librería ya no es soportada. De nuevo, a empezar desde cero, o casi cero.&lt;/p&gt; &lt;h3&gt;Arquitectura y patrones&lt;/h3&gt; &lt;p&gt;Por lo menos, alguien piensa en cómo hacer sistemas: en los estilos arquitectónicos, en descubrir patrones (soluciones a problemas, que se pueden aplicar en distintos contextos) y demás. Estudiamos esos conceptos, ilusionados por encontrar la &amp;quot;silver bullet&amp;quot;, la bala de plata que mate todos los vampiros que amenazan todo nuestro esfuerzo de creación de software.&lt;/p&gt; &lt;p&gt;Pero si examinan cualquiera de esos principios, implican algo: un montón de trabajo. La necesidad de partir los sistemas (nacidos de la complejidad, de nuestras limitaciones como humanos), hacen que cada trabajo que encaremos, implique la generación de multitud de elementos: desde una capa de presentación, hasta una capa de datos, desde una fachada de servicio, hasta un gateway de grabación de entidades, desde una service interface tecnológica, basada en servicios web, hasta conversores de entidades a mensajes y viceversa.&lt;/p&gt; &lt;p&gt;De nuevo, tenemos soluciones, pero mucho trabajo.&lt;/p&gt; &lt;h3&gt;Look ma, no code&lt;/h3&gt; &lt;p&gt;Otra solución intentada, es generar pantallas, páginas, funcionalidad en &amp;quot;runtime&amp;quot;, en ejecución. Cansados de las mismas páginas y menúes, y otros elementos, decidimos poner cómo es el formulario y qué tabla actualizar, en metadata. Esta metadata puede estar en XML on en una base de datos, o donde decidamos.&lt;/p&gt; &lt;p&gt;Pero es muy dificil producir un sistema que contemple todo. Sólo algunas pantallas se podrán armar dinámicamente en ejecución. Y dependiendo de la tecnología, habrá que aprender y probar miles de detalles de reflection, creación dinámica de controles, y más. Y cuando al final terminamos de hacer algo potable en ASP, aparece ASP.NET 1.x. Y cuando finalmente creamos controles con ASP.NET 1.x, aparecen master pages y otros controles, en ASP.NET 2.x. Lo mismo si creamos controles &amp;quot;on the fly&amp;quot; para JSP, y luego aparece JSF.&lt;/p&gt; &lt;p&gt;No es una solución que me desagrade, pero notemos que implica de nuevo, una montaña de trabajo, que puede quedar obsoleta en cualquier momento.&lt;/p&gt; &lt;h3&gt;Aprendiendo, aprendiendo&lt;/h3&gt; &lt;p&gt;Ya sea que pasamos de Visual Fox a .NET, ya sea que conocemos .NET pero queremos aprender conceptos de arquitectura, ya sea conocemos arquitectura, pero queremos manejar un framework como NHibernate o Struts, ya sea conocemos EJB y queremos aprender EJB3, todos esas necesidades de aprendizaje, o la mayoría, son causadas por lo que vimos hasta acá: el cambio permanente, el aumento de la complejidad, y la necesidad de seguir creando software que esté a la altura de lo que los demás están construyendo.&lt;/p&gt; &lt;p&gt;Yo dicto cerca de una docena de clases por semana, de temas tan diversos como PHP, PHP5, patrones, estilos arquitectónicos, Java, JSP, Struts, Spring, Hibernate, EJB2, Jboss, Tomcat, JSF, .NET, Ajax, Windows Workflow Foundation, y me falta abarcar corte y confección y estamos hechos. Veo llegar asistentes a los cursos, y trato de convencerlos que el curso no es del tema que dice el título del curso: no es aprender un tema, que dentro de seis meses va a cambiar. Trato (no siempre lo consigo, debido a limitaciones de mi expresión), de hacer ver que todos esos temas, son tecnologías para resolver problemas. Y trato de advertir, percatar, cuáles son los problemas, y las causas de que tengamos esos problemas. Trato de transmitir, que si vienen a un curso C1, y no ven más allá del tema, dentro de seis meses van a venir al curso C2, que será una simple actualización del anterior, con las mismas esperanzas que albergaban al estudiar C1. Trato de convencerlos de que no vengan más a otro curso: que cada tecnología pasa, lo importante está en otro lado.&lt;/p&gt; &lt;p&gt;Quisiera que cada asistente viera, entonces, más allá del tema circunstancial del curso. Aprender una tecnología, sin pensar más allá, es casi una pérdida de tiempo.&lt;/p&gt; &lt;p&gt;Todos mis cursos, son iguales: no trato de enseñar el tema, sino algo más, algo que trasciende el tema que sirve de excusa al curso. Espero que este &amp;quot;post&amp;quot; ayude a poner en claro algunos puntos que trato de transmitir. También, me sirve para poner en claro mis propias ideas, y, algo que quizás no se dan cuenta, me permite explayarme, regocijarme, sin necesidad de hablar durante horas (ya estoy viejito, me cansa hablar y hablar, disculpen y tengan piedad...;-)&lt;/p&gt; &lt;h3&gt;Cabecitas, y más cabecitas&lt;/h3&gt; &lt;p&gt;De vez en cuando, aparezco en alguna consultar. El año pasado, me tocó visitar un piso lleno de gente, con computadoras personales en cada escritorio: todos desarrollando. El piso era inmenso, no había paredes, y veía a todo el mundo inclinado sobre sus teclados y pantallas. Sólo se veían las cabecitas.&lt;/p&gt; &lt;p&gt;Pero al acercarme, a ver qué hacía cada grupo, encontré lo que temía: varios estaban generando artefactos, que bien podrían delegarse a que un sistema los genere: cantidad de código repetitivo, que bien podría ser generado automáticamente.&lt;/p&gt; &lt;p&gt;No sé cómo será en su pais. Acá en Argentina, hay cantidad de grupos de desarrollo que necesitan programadores Java. Estoy convencido que la necesidad de esos programadores, es debido a la escasa productividad de muchas herramientas de desarrollo de Java. Un Eclipse pelado, no es un Visual Studio. Y en Java, hay multitud de subtecnologías para elegir, cada una con su propia complejidad. Vayan sino a ver un archivo de configuración de Struts o Struts2, un mapeo del Hibernate, o un archivo de configuración de Spring, o un ejb-jar de Enterprise Java Beans. Se los regalo: son obra del diablo. Claro, hay plugins, y demás utilitarios para generar algo de eso. Cada uno trabaja a su manera, sin colaborar con lo demás que nos toque.&lt;/p&gt; &lt;p&gt;Creo que mucho de esa fuerza de programación, se podría aprovechar de forma más eficiente. Creo que a veces, programamos, de la misma forma que cosechábamos hace un siglo el trigo: llamábamos a una multitud de gente, le dábamos una hoz a cada uno, y a trabajar. Hoy una cosechadora hace el mismo trabajo. Recordemos alguna historia de las fábricas japonesas: cuando se automatizó gran parte de la línea de producción, ¿hubo despidos? No, se utilizó la gente, no para apretar tornillos, sino para controlar la calidad, y encargarse de las tareas que no podía realizar un simple robot.&lt;/p&gt; &lt;h3&gt;Herramientas y agentes&lt;/h3&gt; &lt;p&gt;J.P.Plauger, mítico programador, creador de compiladores, empresas y libros, me llamó&amp;nbsp;la atención, en una artículo suyo de hace ya más de una década, sobre algo que pasó en la historia humana: por un lado, aparecieron herramientas, cosas que usamos, para hacer lo que queremos hacer, pero de forma más fácil. Pero también aparecieron en su tiempo, los agentes: otros organismos que hacen ellos, lo que no queremos hacer nosotros. Desde animales de carga, hasta, me temo, esclavos humanos.&lt;/p&gt; &lt;p&gt;Hoy, en desarrollo de software, tenemos muchas herramientas. Pero aún la mejor IDE, nos obliga a sentarnos enfrente, y armar las ventanas arrastrando de a uno los botones. ¿No se podrá delegar gran parte de ese trabajo en un agente de software? Un generador de código puede ser más que un wizard, o un activo de una &amp;quot;software factory&amp;quot; de la IDE de moda: puede ser un sistema experto, que tome decisiones, que dado un modelo, llegue más allá de lo automático. Tal vez, este es el aspecto más oscuro de explicar ahora en este &amp;quot;post&amp;quot;. Recuerden: podemos conseguir más que una herramiente, un agente. Algo más sobre &amp;quot;inteligencia artificial&amp;quot; más abajo.&lt;/p&gt; &lt;h3&gt;Domain Specific Languages&lt;/h3&gt; &lt;p&gt;Vimos que una estrategia, como la empleada en la compilación, implica:&lt;/p&gt; &lt;p&gt;- un lenguaje de alto nivel&lt;/p&gt; &lt;p&gt;- una herramienta que pase de ese lenguaje a algo que entienda la máquina&lt;/p&gt; &lt;p&gt;Hace un tiempo, aparece el concepto de DSL (Domain Specific Languages). En lugar de usar un lenguaje que modele en alto nivel algo genérico (como algunos pretenden con UML), se pueden inventar lenguajes que modelen, expresen, las necesidades que tenemos y que haya herramientas que, interpretando, procesando esos modelos expresados en un lenguaje específicamente orientado al dominio a solucionar, vayan generando el artefacto final necesario para pasar del modelo de alto nivel a algo más cercano a la máquina.&lt;/p&gt; &lt;p&gt;Alguien puede pensar que nunca usó un DSL. Creo que podría estar equivocado. Veamos un par de casos. Tomemos el lenguaje SQL. Un comando como&lt;/p&gt; &lt;p&gt;select * from employee&lt;/p&gt; &lt;p&gt;nos soluciona un conjunto de detalles, que antes, con un sistema indexado (un ISAM, un venerable Btrieve, y otros), implicaba programar un cursor, obtener cada estructura de registro, pasarla a una estructura de memoria, recorrer programáticamente un índice, recordar que el campo nombre está en tal posición, y más y más detalles. Vean cómo el lenguaje SQL es un DSL: no es un lenguaje genérico. No sirve para hacer sistema cualesquiera. Nadie escribe formularios en SQL o hace cálculos científicos o rutinas recursivas. Sólo está dedicado a solucionar el tema de acceso a datos. Pero ha sido lo bastante potente y flexible, para que hoy lo hayamos adoptado en cada recoveco de nuestros sistemas. Detengámonos en esos puntos:&lt;/p&gt; &lt;p&gt;- No es genérico, es específico de un dominio&lt;/p&gt; &lt;p&gt;- Es flexible&lt;/p&gt; &lt;p&gt;- Hace lo que necesitamos hacer, por nosotros&lt;/p&gt; &lt;p&gt;Segundo caso de DSL: un lenguaje no tiene que ser un lenguaje textual. Tomemos el caso de un DSL exitosísimo, que cambió la forma de programar en Windows. Es el caso del diseñador de formularios del venerable Visual Basic del milenio pasado. Vean cómo dibujando un formulario, Visual Basic se encarga de armar lo que nos hubiera llevado páginas y páginas de código C++. Algunos de Uds. recordarán la alienación que era codificar un simple &amp;quot;Hello, World&amp;quot;, con Visual C++, siguiendo las recomendaciones del bueno de Petzold. Visual Basic nos liberó de eso. Alguien podría haber pensado: no hace lo mismo que C++, no es tan eficiente, no permite ser tan flexible... Bullshit.... Visual Basic nos ayudó por más de una década, con un DSL gráfico.&lt;/p&gt; &lt;h3&gt;Algunos generadores de código&lt;/h3&gt; &lt;p&gt;Algunos de Uds ya habrán experimentado con utilitarios de generación de código. En un próximo párrafo, mencionaré lo que yo pediría a un generador. Pero veamos ahora algunas limitaciones.&lt;/p&gt; &lt;p&gt;Primero: el generador sólo genera lo que él quiere. Típico de generadores &amp;quot;profesionales&amp;quot;, que sólo producen lo que los creadores del generador imaginaron. Es difícil, y en algunos casos, imposible, extenderlo más allá de lo que hacen actualmente. Variante de esto: sólo genera código para entidades, o sólo para una tecnología, o sólo para EJB, o sólo para.... y puedo seguir. Claro, la herramienta soluciona el problema, y al comienzo estamos chochos de haberla encontrado. Pero advertiría desde ahora, que encontrarán limitaciones.&lt;/p&gt; &lt;p&gt;Segundo: el generador sólo parte de un modelo predeterminado (típicamente de una estructura de tablas de base de datos). Creo haberlos convencido que hay más bajo el sol que generar entidades y mapeadores. Hay colecciones inmensas de artefactos que tenemos que generar en cualquier sistema no trivial. Y seguirán apareciendo, por lo menos, en el futuro cercano. Si el generador sólo está pensado para partir de un modelo determinado, nos limita en lo que podemos pedirle. La historia nos ha mostrado, que siempre necesitamos algo más.&lt;/p&gt; &lt;p&gt;Tercero: el generador es cerrado, no se puede aprovechar e integrar en sistemas nuestros, o no entrega el código de base, o no permite armar plantillas y demás auxiliares.&lt;/p&gt; &lt;p&gt;Puedo seguir enumerando problemas. Mencionemos uno más: hay quien menciona que utilizó generadores de código, pero sólo lo usa para generar el código inicial de un sistema, y luego ya modifica el código generado, y no puede regenerar sin perder los cambios que hizo. Sugerencia: pongan en claro qué artefactos se generan automáticamente, y cuáles son los generados manualmente. Cuando Uds compilan un ejecutable, y necesitan cambiar un algoritmo, no van y cambian los bits del .exe. No: van al modelo, al lenguaje de programación, lo cambian y compilan de nuevo. Lo mismo deberíamos conseguir algún día, con generación de código. Como no podemos generar todo, debemos tener la disciplina de decidir cuáles artefactos son generados por el utilitario, y cuáles son los artefactos nuestros. En algunos casos, en los repositorios de código, en un CVS, cuando se trabaja en grupo, NO SE GUARDA lo generado automáticamente: solamente se guarda el modelo, y lo generado manualmente. Esto refuerza la responsabilidad de no tocar ese código automático: cualquier cambio manual que hagamos sobre ellos, no se guardará en el repositorio común.&lt;/p&gt; &lt;h3&gt;El camino del demonio&lt;/h3&gt; &lt;p&gt;Quisiera insertar ahora, en este momento, una advertencia. Todos podemos hacer un generador de código, o utilizar alguno ya armado. Algunas de las características deseables, fueron apareciendo en la discusión, y quedará más claro en la próxima sección. Pero levanto la mano para que no sigan un camino: XSLT.&lt;/p&gt; &lt;p&gt;Podrá ocurrírseles, en algún momento, que el modelo inicial, la metadata de partida, se encuentre en XML. Creo que es una elección pragmática: luego, más adelante, ese modelo se puede dibujar, crear con utilitarios más simpáticos o gráficos, pero un buen XML sirve como un DSL para un dominio que querramos manejar.&lt;/p&gt; &lt;p&gt;Pero no se les ocurra que podrán generar lo que quieran con XSLT (transformaciones de XML). XSLT es el camino del demonio. Para cualquier cosa no trivial, es algo que complica el universo, de una forma no predecible. Es como tratar de rascarse la oreja izquierda con el pie derecho. Poder se puede, pero les va a costar. Trabajar con XSLT es como un problema de ingenio. ¿Recuerdan el acertijo de tener un bote, dos orillas, y en una una oveca, una lechuga y un lobo, y sólo caben dos en el bote, aparte de uno? Bien, algo así es tratar de manejar XSLT para generar código. &amp;quot;Forget it&amp;quot;, XSLT caca.... ;-)&lt;/p&gt; &lt;h3&gt;Hacia un generador de código&lt;/h3&gt; &lt;p&gt;¿Qué le pediríamos entonces, a un generador de código? Gran pregunta, intentemos algunas respuestas:&lt;/p&gt; &lt;p&gt;- Que genere código que hubiéramos generado nosotros: si genera código inentendible, estamos en mal camino. Ese es el problema de varios wizards y demás herramientas: hacen lo que ellas quieren, no lo que nosotros queremos.&lt;/p&gt; &lt;p&gt;- Que genere cualquier texto que nos imaginemos que necesitamos: no basta que genere lo que el generador de código decida. Debe ser lo bastante flexible, para que podamos generar lo que querramos: desde una simple entidad, a un mapeo de Hibernate, desde una página web, hasta un mensaje de Windows Communication Foundation, desde el archivo de configuración de Struts, hasta el interminable ejb-jar.xml que nos pide el JBoss versión 17.84 que tengamos el año que viene.&lt;/p&gt; &lt;p&gt;- Que parta de un modelo simple, o compuesto, pero libre: no que parta de una base de datos, y sólo genere entidades y mapeadores. Necesitamos más flexibilidad. Ya vimos los que nos pasa en la vida real: todo cambia, necesitamos multitud de artefactos. Cualquier inversión en un generador de código que no permita incluir un modelo libre, me parece riesgosa. Creo que como prueba ácida, le pediría a un generador, que permita, desde un modelo libre, generar todo programa &amp;quot;Hello, World&amp;quot; que se nos ocurra. Si una herramienta no puede obtener ese resultado, estamos en el horno.&lt;/p&gt; &lt;p&gt;- Que permita escribir los templates, plantillas que querramos, y generarlas en grupo, en serie, en paralelo, o como querramos. Tanto el orden y enumeración de artefactos a generar, como las plantillas, como la toma de decisiones (generar de tal forma o no), debe estar bajo control del utilitario, y bajo control nuestro.&lt;/p&gt; &lt;p&gt;- Que permita generar desde un modelo, al cambiarlo, de forma fácil: si para generar los artefactos, por un cambio en el modelo, hay que dar cuarenta pasos, de nuevo estamos en problema. Compilar hoy es una tecla. Lo mismo debe ser la generación de código.&lt;/p&gt; &lt;h3&gt;Dunga dunga un ratito&lt;/h3&gt; &lt;p&gt;De alguna forma, un generador de código ideal no estará atado a una tecnología. Siempre habrá alguna &amp;quot;better mousetrap&amp;quot;, siempre alguien inventará alguna nueva forma de hacer algo, siempre habrá un ruso&amp;nbsp;con insomnio, o un hindú sin novia, que no tiene otra cosa que hacer que crear algo nuevo,&amp;nbsp;ya sea en forma de librería, framework, patrón, o estilo arquitectónico. Un generador de código debe ser agnóstico de la tecnología, de las modas, de las soluciones actuales y futuras.&lt;/p&gt; &lt;p&gt;El generador de código que adoptemos, debe poder adaptarse a lo que querramos hoy y mañana y pasado mañana. La estrategia es: no importa la tecnología, el patrón o el framework que aparezca, nuestro generador deberá aprovecharse de lo que surja. Es lo que llamo la estrategia &amp;quot;dunga dunga&amp;quot;: si aparece una nueva tecnología T1, le hacemos &amp;quot;dunga dunga&amp;quot; a T1, si aparece un nuevo framework PiruloStruts, adaptamos nuestras plantillas a aprovecharse de ese framework, &amp;quot;dunga dunga&amp;quot; a PiruloStruts. Es como un maestro de aikido: siempre habrá alguien más fuerte, sólo hay que utilizar la fuerza del otro, para vencerlo.&lt;/p&gt; &lt;h3&gt;Mi corazoncito&lt;/h3&gt; &lt;p&gt;Claro, los que asistieron a algunas de mis charlas, ya conocen el final: tengo mi propio generador de código, el proyecto de código abierto &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;AjGenesis&lt;/a&gt;. Lo pueden bajar, probar, examinar, integrar, modificar, hagan lo que quieran. Pero no digan que no les mostré la luz... ;-) ;-)&lt;/p&gt; &lt;p&gt;Se basa en:&lt;/p&gt; &lt;p&gt;- Tener un modelo totalmente libre, que hoy está serializado en archivos XML.&lt;/p&gt; &lt;p&gt;- Plantillas que generan artefactos de texto&lt;/p&gt; &lt;p&gt;- Tareas programables, que cargan los modelos, ejecutan lo que uno quiera, y son invocables desde programas nuestros, desde la línea de comando, o desde un utilitario como el NAnt.&lt;/p&gt; &lt;p&gt;Entonces, se arma uno o varios modelos, que expresan lo que Uds quieran de su sistema, de forma independiente de la plataforma, y luego, adosándole modelos (uno o varios, de nuevo libres), que indican la tecnología a usar, y escribiendo las plantillas que Uds. quieran, generan lo que se les ocurra.&lt;/p&gt; &lt;p&gt;Pueden leer sobre el modelo libre que usa en:&lt;/p&gt; &lt;p&gt;&lt;a title="Generando C&amp;oacute;digo- Hello World con AjGenesis" href="http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx"&gt;Generando Código- Hello World con AjGenesis&lt;/a&gt;&lt;/p&gt; &lt;p&gt;(como el modelo está serializado en texto... adivinen... se puede generar desde el mismo generador!!!). Esto implica:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;M1 (de alto nivel) ===&amp;gt; Templates+AjGenesis ==&amp;gt; M2 (de nivel medio) ==&amp;gt; Templates+AjGenesis ==&amp;gt; Mn..... ==&amp;gt; Artefactos de texto finales&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;¿Se entiende? Si uno tiene pensado un modelo M, bien puede generarlo desde otro modelo que alguien traiga: por ejemplo, desde la estructura de base de datos, o desde un gráfico UML serializado en XMI, o lo que se invente mañana. Sólo es cuestión de generar el modelo desde el cual queremos partir. Hoy lo generamos manualmente: pero tengo algunos intentos promisorios, para que el modelo que necesite, se genere desde otro modelo que tengamos más a mano.&lt;/p&gt; &lt;p&gt;(Notablemente, ahora, muchos generadores de código más &amp;quot;profesionales&amp;quot;, están adoptando esta estrategia: modelo libre.... vieron la luz... :-) ;-)&lt;/p&gt; &lt;p&gt;Pueden ver algunos ejemplos no triviales:&lt;/p&gt; &lt;p&gt;&lt;a title="Generando aplicaciones con AjGenesis" href="http://msmvps.com/blogs/lopez/archive/2007/06/25/generando-aplicaciones-con-ajgenesis.aspx"&gt;Generando aplicaciones con AjGenesis&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Desde un modelo inventado para el ejemplo, se producen aplicaciones completas en VB.NET 1.x, VB.NET 2, C# 1.x, C# 2, JSP, usando patrones de Business Entities/Business Components a la Microsoft, o usando Domain-Driven Design de Evans, usando MySql o SQL Server, usando Gateways, Data Mappers, o Hibernate, o NHibernate. O lo que vuestra imaginación quiera: el cielo es el límite.&lt;/p&gt; &lt;p&gt;Ese modelo del ejemplo, hoy se genera manualmente. Tengo utilitarios, basados en AjGenesis, que generan ese modelo, desde un modelo más esquemático. Y estoy trabajando para generarlo desde otras fuentes. Si el modelo a usar se puede expresar en texto, PUEDE SER GENERADO por el propio sistema, más un sistema experto. No imagino una aplicación más inmediata de la &amp;quot;inteligencia artificial&amp;quot;. Imagino agentes inteligentes, que colaboren en una red compartida, cada uno generando parte del modelo, cada uno consumiendo algo que otro produce, y colaborando, para generar un sistema... Sí, ya sé, tengo que tomar la píldora verde, en lugar de la roja... ;-)&lt;/p&gt; &lt;p&gt;Más artículos sobre generación de código en:&lt;/p&gt; &lt;p&gt;&lt;a title="Generaci&amp;oacute;n de C&amp;oacute;digo" href="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx"&gt;Generación de Código&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Pero no tiene mucha documentación. Si Ud. lo encuentra útil, le pediría:&lt;/p&gt; &lt;p&gt;- Escribir, comentar sobre su experiencia, en la web (lo que no está bajo Google, no existe...:-)&lt;/p&gt; &lt;p&gt;- Compartir los templates, o por lo menos, comentar cuáles creó, para qué, y sus resultados&lt;/p&gt; &lt;p&gt;Estoy trabajando en tener un repositorio de templates en la web, para poder catalogarlos, y que otros usuarios puedan (no es obligación) publicar las plantillas o modificaciones que le resulten útiles.&lt;/p&gt; &lt;p&gt;Generadores de código más &amp;quot;armados&amp;quot; (pero me parece, sinceramente, menos flexibles), desde:&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.codegeneration.net/"&gt;http://www.codegeneration.net/&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;Más allá de la generación de código&lt;/h3&gt; &lt;p&gt;Hay que tener claro algo: la generación de código es sólo una solución pragmática a la situación actual. No implica abandonar todo pensamiento crítico, toda esperanza de mejora en la creación de sofware. Creo que vamos por buen camino: tenemos arquitectura, patrones, vamos conociendo cada vez más, cómo generar software de calidad. Estamos, creo, en una etapa aristotélica de nuestra disciplina: estamos ordenando conocimientos, clasificando datos, comenzando a darnos cuenta de cuáles son los esquemas, relaciones, problemas esenciales. Pero nos falta aún encontrar a un Galileo o Newton de los sistemas (mi natural modestia, me impide señarlar a un candidato que tengo &amp;quot;in pectore&amp;quot;... ;-).&lt;/p&gt; &lt;h3&gt;Conclusión&lt;/h3&gt; &lt;p&gt;Estudien cómo hacen los sistemas. Consigan dominar la tecnología que tienen entre manos. Descubran lo común a todo lo que hacen. Y en algún momento, adopten alguna herramienta, que les ayude a generar automáticamente lo mismo, que Uds. hubieran generado. Dedicar la inteligencia y el tiempo, donde el tiempo y la inteligencia se necesitan. Dejemos de escribir palabras de lenguaje: creemos software.&lt;/p&gt; &lt;p&gt;La mejora herramienta está entre nuestras orejas, apliquemos la neurona, generación de código, vermuth con papa fritas, y good show!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1081900" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item><item><title>Generando Código: Hello World con AjGenesis</title><link>http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx</link><pubDate>Sun, 19 Nov 2006 23:24:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:308486</guid><dc:creator>lopez</dc:creator><slash:comments>30</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=308486</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2006/11/19/generando-c-digo-hello-world-con-ajgenesis.aspx#comments</comments><description>&lt;p&gt;&lt;br /&gt;Mi proyecto preferido, &lt;a class="" href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;, consiste en un generador de código, escrito en VB.NET. Es un proyecto de código abierto, con una licencia tipo BSD, que permite utilizarlo en cualquier proyecto que quieran. Se puede usar como librería, invocado desde nuestro proyecto, se puede invocar desde la línea de comando, o puede ser utilizado desde el poderoso &lt;a class="" href="http://nant.sourceforge.net/" target="_blank"&gt;NAnt&lt;/a&gt; (esto último me permitió organizar mejor las tareas que realiza el generador de código).&lt;/p&gt;
&lt;p&gt;En la página del proyecto (y en el proyecto mismo) hay multitud de ejemplos, que generan código desde un modelo, usando plantillas. Los ejemplos generan código PHP, Java, JSP, VB.NET, C#, ASP.NET, y hasta scripts de base de datos y procedimientos almacenados. Quisiera destacar dos puntos:&lt;/p&gt;
&lt;p&gt;- El modelo del que parte es totalmente definible por el usuario&lt;/p&gt;
&lt;p&gt;- Las tareas y plantillas a aplicar son totalmente programables y controlables&lt;/p&gt;
&lt;p&gt;Esto lo diferencia de otros generadores. Ud. puede hacerse su propio modelo, y sus propias plantillas, para generar los artefactos de texto que prefiera. Otros sistemas parten de la base de datos, y sólo generan un grupo de artefactos de textos predefinidos (por ejemplo, POJOs, o DAOs). Pero con AjGenesis puede generar lo que Ud. quiera.&lt;/p&gt;
&lt;p&gt;Para ejemplificar, este artículo se dedica a modelar algo que, si bien no es lo último en tecnología, es la primera prueba que debe pasar un generador de código: modelar y generar un viejo pero entrañable &amp;quot;Hello, World&amp;quot; (programa que encontré por primera vez en el venerable &amp;quot;The C Programming Language&amp;quot; de los buenos de Kernighan y Ritchie).&lt;/p&gt;
&lt;p&gt;Los archivos de este ejemplo, pueden bajarse de &lt;a class="" href="http://www.ajlopez.com/downloads/HelloWorld1.zip"&gt;HelloWorld1.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Primero, el modelo. Como menciono en mis charlas, el modelo es una simplificación de la realidad. El modelo, por ejemplo, un mapa, no es la realidad, el territorio. En el caso de los modelos de AjGenesis, se trata de crear inicialmente, un modelo que muestre lo variable de nuestro sistema. En el caso de un HelloWorld, lo que quisierámos modelar como variable, es el mensaje. Entonces, creamos en un directorio de trabajo, el archivo &lt;strong&gt;Project.xml&lt;/strong&gt;:&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN:0in 0in 0pt;"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;Project&amp;gt;&lt;br /&gt;&amp;lt;Message&amp;gt;Hello World, by AjGenesis&amp;lt;/Message&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Este es el primer paso. Vean que no tuvimos que usar un modelo predefinido, simplemente, lo escribimos en un documento XML bien formado. Nada de schemas, nada DTDs, o bichos raros. Solamente nuestra creatividad.&lt;/p&gt;
&lt;p&gt;El segundo paso es elegir la tecnología (lenguaje, plataforma, framework, base de datos), que vamos a utilizar, y escribir (o reutilizar) plantillas. Decidimos crear un ejemplo en VB.NET, un simple programa de consola. La plantilla la escribimos en el archivo &lt;strong&gt;HelloVb.tpl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;#39;&lt;br /&gt;&amp;#39; Hello World demo&lt;br /&gt;&amp;#39; generated by AjGenesis&lt;br /&gt;&amp;#39; &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;http://www.ajlopez.com/ajgenesis&lt;/a&gt;&lt;br /&gt;&amp;#39;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;Module HelloWorld&lt;br /&gt;&amp;nbsp;Public Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Console.WriteLine(&amp;quot;${Project.Message}&amp;quot;)&lt;br /&gt;&amp;nbsp;End Sub&lt;br /&gt;End Module&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&lt;/span&gt;Acá aparece una característica de las plantillas: permiten acceder y utilizar en la salida, los datos del modelo. Al escribir Project.Message entre ${ y }, le indicaros al procesador AjGenesis, que cuando trabaje sobre esta plantilla, reemplace ese texto por el valor de la rama Project/Message en nuestro modelo. Vemos que no usamos una notación XML o XPath para referirnos a algo del modelo. El modelo inicial está serializado en XML, pero AjGenesis lo levanta a memoria, y nos lo deja como un objeto con propiedades.&lt;/p&gt;
&lt;p&gt;Hubiéramos podido escribir el modelo como&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;Project Message=&amp;quot;Hello World, by AjGenesis&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;El modelo en memoria sería el mismo. Aunque ahora Message está como atributo, para nuestra plantilla sigue siendo la propiedad Message del objeto Project.&lt;/p&gt;
&lt;p&gt;Ya tenemos el modelo, y la plantilla. Necesitamos bajar y expandir el &lt;a class="" href="http://www.ajlopez.com/downloads/AjGenesis-0.4.3.zip"&gt;AjGenesis-0.4.3.zip&lt;/a&gt; (versión en desarrollo, las anteriores versiones están en el directorio de fuentes SourceForge del proyecto). En esa versión, hay un directorio bin con librerías y algún ejecutable. El &lt;strong&gt;AjGenesis.Console.exe&lt;/strong&gt; es el programa que puede invocarse para tomar el modelo y la plantilla, y generar un archivo, así:&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;AjGenesis.Console Project.xml HelloWorldVb.tpl HelloWorld.vb&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Los parámetros se explican así:&lt;/p&gt;
&lt;p&gt;Archivo .xml: cuando encuentra en la lista de parámetros un archivo XML, AjGenesis lo carga en su ambiente de variables. El nodo inicial del XML pasa a ser el nombre de la variable que contiene al modelo.&lt;/p&gt;
&lt;p&gt;Archivo .tpl: lo toma como plantilla, y lo procesa, generando un archivo con el nombre del siguiente parámetro.&lt;/p&gt;
&lt;p&gt;Por supuesto, para que esto funcione, o deberemos poner la ruta completa del ejecutable AjGenesis.Console, o deberemos incluir el directorio bin de AjGenesis en el PATH de nuestro ambiente.&lt;/p&gt;
&lt;p&gt;Los parámetros los procesa en orden. Podríamos poner más de un modelo, más de un archivo XML. Por ejemplo, un segundo archivo XML podría describir la tecnología de base de datos a usar, o el nombre de la empresa que está usando el modelo, o cualquier otra cosa que se nos ocurra. Sería conveniente en este caso que el segundo archivo XML tenga un nodo raíz distinto de Project, porque así no sobreescribe al modelo del anterior archivo. También podríamos colocar varios archivos de plantilla con su correspondiente archivo resultado, en una misma invocación.&lt;/p&gt;
&lt;p&gt;Si ejecutamos entonces el comando de arriba (necesitamos un framework .NET instalado, recordemos que AjGenesis está escrito en .NET), se genera el archivo &lt;strong&gt;HelloWorld.vb&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;#39;&lt;br /&gt;&amp;#39; Hello World demo&lt;br /&gt;&amp;#39; generated by AjGenesis&lt;br /&gt;&amp;#39; &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;http://www.ajlopez.com/ajgenesis&lt;/a&gt;&lt;br /&gt;&amp;#39;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;Module HelloWorld&lt;br /&gt;&amp;nbsp;Public Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Console.WriteLine(&amp;quot;Hello World, by AjGenesis&amp;quot;)&lt;br /&gt;&amp;nbsp;End Sub&lt;br /&gt;End Module&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;No vamos a decir &amp;quot;Uy que bruto..&amp;quot;, pero es el primer paso.&lt;/p&gt;
&lt;p&gt;Pero vayamos más alla. Supongamos que ahora, con el mismo modelo, queremos generar nuestro gran sistema HelloWorld, en Java. Las presiones del mercado, nuestros clientes, nos piden la nueva versión en el lenguaje multiplataforma Java, y nosotros estamos acá para servirlos. Bien, manos a la obra, creamos un archivo &lt;strong&gt;HelloWorldJava.tpl&lt;/strong&gt; con&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;/**&lt;br /&gt;* Hello World demo&lt;br /&gt;* generated by AjGenesis&lt;br /&gt;* &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;http://www.ajlopez.com/ajgenesis&lt;/a&gt;&lt;br /&gt;*/&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;public class HelloWorld {&lt;br /&gt;&amp;nbsp;public static void main(String [] args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.out.println(&amp;quot;${Project.Message}&amp;quot;);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;y ejecutamos en la línea de comando&lt;/p&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;mso-bidi-font-size:10.0pt;"&gt;&lt;font size="3"&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;AjGenesis.Console Project.xml HelloWorldJava.tpl HelloWorld.java&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/font&gt;&lt;/span&gt;y voilá, se genera el archivo &lt;strong&gt;HelloWorld.java&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;/**&lt;br /&gt;* Hello World demo&lt;br /&gt;* generated by AjGenesis&lt;br /&gt;* &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;&lt;span style="COLOR:windowtext;TEXT-DECORATION:none;text-underline:none;"&gt;http://www.ajlopez.com/ajgenesis&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;*/&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;public class HelloWorld {&lt;br /&gt;&amp;nbsp;public static void main(String [] args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.out.println(&amp;quot;Hello World, by AjGenesis&amp;quot;);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Ya estamos cebados. Vamos por un ejemplo más flexible. Quisiéramos ahora generar el programa VB.NET, el programa C#, el programa Java, y que el nombre de la clase, del programa, sea algo variable (en las plantillas anteriores aparecía siempre HelloWorld como nombre del archivo y de la clase o módulo).&lt;/p&gt;
&lt;p&gt;Los archivos de este segundo ejemplo se pueden bajar de &lt;a class="" href="http://www.ajlopez.com/downloads/HelloWorld2.zip"&gt;HelloWorld2.zip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Para esto, en otro directorio, creamos el archivo &lt;strong&gt;Project.xml&lt;/strong&gt; con el contenido&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;Project&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;Name&amp;gt;HelloWorld&amp;lt;/Name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;Description&amp;gt;Hello World Demostration&amp;lt;/Description&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;Message&amp;gt;Hello World, by AjGenesis&amp;lt;/Message&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Y escribimos las plantillas &lt;strong&gt;ModuleVb.tpl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;#39;&lt;br /&gt;&amp;#39; ${Project.Description}&lt;br /&gt;&amp;#39; generated by AjGenesis&lt;br /&gt;&amp;#39; &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;&lt;span style="COLOR:windowtext;TEXT-DECORATION:none;text-underline:none;"&gt;http://www.ajlopez.com/ajgenesis&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&amp;#39;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;Module ${Project.Name}&lt;br /&gt;&amp;nbsp;Public Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.Console.WriteLine(&amp;quot;${Project.Message}&amp;quot;)&lt;br /&gt;&amp;nbsp;End Sub&lt;br /&gt;End Module&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;y &lt;strong&gt;ClassJava.tpl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;/**&lt;br /&gt;* ${Project.Description}&lt;br /&gt;* generated by AjGenesis&lt;br /&gt;* &lt;a href="http://www.ajlopez.com/ajgenesis"&gt;&lt;span style="COLOR:windowtext;TEXT-DECORATION:none;text-underline:none;"&gt;http://www.ajlopez.com/ajgenesis&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;*/&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;public class ${Project.Name} {&lt;br /&gt;&amp;nbsp;public static void main(String [] args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;System.out.println(&amp;quot;${Project.Message}&amp;quot;);&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Estudiemos otra característica de &lt;a class="" href="http://www.ajlopez.com/ajgenesis" target="_blank"&gt;AjGenesis&lt;/a&gt;: la capacidad de ejecutar un script, en un lenguaje denominado informalmente AjBasic. Creo que esta es una característica poderosa, porque posibilita ir más allá de simplemente la línea de comando. Nos permite manipular programáticamente el modelo y las tareas a realizar. En los ejemplos que encontrarán en la página del proyecto, se usa mucho esta característica, llegándose a producir soluciones completas, con decenas de archivos. Pero veamos nuestro ejemplo.&lt;/p&gt;
&lt;p&gt;El programa lo ingresamos en el archivo &lt;strong&gt;Build.ajg&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;PrintLine &amp;quot;Generating ${Project.Name}&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;TransformerManager.Transform(&amp;quot;ModuleVb.tpl&amp;quot;, &amp;quot;${Project.Name}.vb&amp;quot;, Environment)&lt;br /&gt;TransformerManager.Transform(&amp;quot;ClassJava.tpl&amp;quot;,&amp;quot;${Project.Name}.java&amp;quot;, Environment)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;El lenguaje AjBasic, tiene algún verbo predefinido, como el autodescriptivo PrintLine. Notemos que, como en otros lenguajes de scripting, tiene expansión de expresiones en los strings. Esto es, cuando en un texto entre doble comillas (una constante string), ubica una expresión entre ${ y }, la evalúa y la reemplaza por el valor resultante. Muchos de Uds. reconoceran aquí una conducta similar a otros lenguajes de scripting de Unix/Linux, o a PHP, o al Expression Language de JSP 2.x.&lt;/p&gt;
&lt;p&gt;La variable TransformerManager es una de las pocas predefinidas. No he definido muchas, y Uds. pueden agregar variables al ambiente de AjGenesis. Pero TransformerManager sirve para invocar programáticamente lo que hacemos desde la línea de comando. Así, el primer parámetro de su método Transform el archivo plantilla, el segundo parámetro es el archivo a generar, y el tercero, la colección de variables definida (en el ejemplo usamos Environment, otra de las variables predefinidas, que justamente es el diccionario de variables que ahora están disponibles en la evaluación de este script).&lt;/p&gt;
&lt;p&gt;Ejecutamos lo anterior con&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;AjGenesis.Console Project.xml Build.ajg&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;El programa de consola está preparado para ejecutar cada parámetro que tenga la extensión .ajg, interpretándolo como un texto AjBasic.&lt;/p&gt;
&lt;p&gt;Pero podemos ir más allá. El año pasado (el proyecto AjGenesis ya lleva sus años en desarollo), incorporé soporte de &lt;a class="" href="http://nant.sourceforge.net/" target="_blank"&gt;NAnt&lt;/a&gt;. Esto lo hice escribiendo tareas (Tasks) de AjGenesis que pueden invocarse desde ese gran utilitario. Yo uso además, el utilitario &lt;a class="" href="http://www.swoogan.com/nantgui.html" target="_blank"&gt;NAnt-GUI&lt;/a&gt; para ejecutar los archivos .build desde una ventana gráfica.&lt;/p&gt;
&lt;p&gt;Escribamos un archivo &lt;strong&gt;default.build&lt;/strong&gt; con el contenido (revise y modifique la property ajgenesis.dir para que refleje el directorio donde ha dejado al AjGenesis):&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;project name=&amp;quot;Example 1&amp;quot; default=&amp;quot;build&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;property name=&amp;quot;ajgenesis.dir&amp;quot; value=&amp;quot;c:/ajlopez/dev/AjGenesis-0.4.3&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;property name=&amp;quot;nanttasks.dir&amp;quot; value=&amp;quot;${ajgenesis.dir}/bin&amp;quot;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;target name=&amp;quot;clean&amp;quot; description=&amp;quot;cleans build directory&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;delete dir=&amp;quot;${build.dir}&amp;quot; verbose=&amp;quot;true&amp;quot; if=&amp;quot;${directory::exists(build.dir)}&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;target name=&amp;quot;loadtasks&amp;quot; description=&amp;quot;loads AjGenesis tasks&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;loadtasks assembly=&amp;quot;${nanttasks.dir}/AjGenesis.NAnt.dll&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;target name=&amp;quot;init&amp;quot; depends=&amp;quot;loadtasks&amp;quot; description=&amp;quot;init the AjGenesis model&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;loadmodel model=&amp;quot;Project.xml&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;target name=&amp;quot;build&amp;quot; depends=&amp;quot;init&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;executetask task=&amp;quot;Build.ajg&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Entonces, desde la línea de comando podemos invocar&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-SIZE:12pt;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;mso-bidi-font-family:Arial;mso-fareast-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-font-size:10.0pt;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;nant&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Si tenemos configurado a ese utilitario, procesa el target default que de build.xml. Yo uso el NAnt-Gui, que me presenta la pantalla&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/downloads/HelloWorld2.gif" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Espero que este artículo les sirva como inicio de explicación a algunas de las características de AjGenesis. Espero escribir un próximo artículo, con ejemplos de uso de AjBasic dentro de las mismas plantillas, uso más intensivo del NAnt, manipulación del modelo en memoria, y generación de aplicaciones completas, en distintas plataformas y tecnologías.&lt;/p&gt;
&lt;p&gt;Si alguien le parece útil, les pido que lo difundan, por ejemplo, con artículo de cómo lo están usando, en su blog.&lt;/p&gt;
&lt;p&gt;Gracias por todo, nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/"&gt;http://www.ajlopez.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=308486" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/PHP/default.aspx">PHP</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Generaci_26002300_243_3B00_n+de+C_26002300_243_3B00_digo/default.aspx">Generaci&amp;#243;n de C&amp;#243;digo</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjGenesis/default.aspx">AjGenesis</category></item></channel></rss>