August 2007 - Posts
Quería comentar brevemente, algunas novedades en C Sharp, que aparecen en su nueva versión. Escribí un proyecto en VS 2008 Beta 2, que pueden bajar desde CSharpNew1.zip.
En una clase, ahora podemos definir directamente las propiedades, sin necesidad de poner las variables: son las propiedades implícitas (implicit properties):
1 public class Supplier
2 {
3 public int SupplierId { get; private set; }
4
5 public string Name { get; set; }
6 public string City { get; set; }
7
8 public Supplier(int Id)
9 {
10 SupplierId = Id;
11 }
12 }
Podemos crear objetos y especificar sus propiedades, en el mismo comando:
1 List<Supplier> suppliers =
2 new List<Supplier> {
3 new Supplier(1) { Name = "John Madison", City = "Washington" },
4 new Supplier(2) { Name = "Ann Arbor", City = "Ohio" },
5 new Supplier(3) { Name = "Don Johnson", City = "Miami" }
6 };
Podemos crear objetos implícitos, sin especificar una clase, solamente basta especificar las propiedades que tenga:
1 var c = new { Name = "John Doe", City = "Everywhere" };
2
3 Console.WriteLine("{0} lives in {1}", c.Name, c.City);
4
A veces, queremos extender la funcionalidad de alguna clase ya armada, con nuevos métodos. En una clase estática, escribimos métodos que reciban un nuevo tipo de parámetro this
1 public static class Extensions
2 {
3 public static void Print(this Supplier supplier)
4 {
5 Console.WriteLine("Supplier {0} {1}", supplier.SupplierId, supplier.Name);
6 }
7 }
8
Esto permite aplicar a todos los objetos de la clase Supplier el nuevo método definido:
1 foreach (Supplier supplier in suppliers)
2 supplier.Print();
Esta característica es usada en gran parte de .NET 3.x, especialmente en LINQ, para extender la funcionalidad de listas y clases ya existentes en el framework.
Capacidades similares (no iguales) tenemos en el nuevo VB.Net.
Gracias a la gente de Southworks y al equipo Tamesis por la ayuda brindada para este post.
Espero escribir sobre otras funcionalidades, de ambos lenguajes. También tengo pendiente escribir sobre Java 6.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Se acaba de anunciar la disponibilidad de la Beta 2 del Entity Framework de Microsoft:
Entity Framework Beta 2 & the 1st Entity Framework Tools CTP Released!
Por un lado tenemos
Entity Framework Beta 2
para bajarnos, y un conjunto de herramientas
Entity Framework Tools CTP
Hay ejemplos en aquí
Siempre pueden seguir su desarrollo siguiendo y participando del blog del ADO.NET Team:
http://blogs.msdn.com/adonet/
¿Qué es el Entity Framework? Bueno, es algo difícil de resumir, pero permite manejar un modelo de objetos (con relaciones entre ellos), expresados en .NET que persisten, gracias a Providers escritos, a distintas bases de datos relacionales (al parecer en Microsoft, han advertido que hay vida más allá del MS SQL Server..;-). Ahora el team se está concentrando en escenarios "la base de datos ya está", y veremos qué pasa con esta movida: ¿podrá suplantar al NHibernate?
Tiene un lenguaje que describe el modelo, de una forma que me pareció rica, más interesante que un ORM.
Pueden leer una introducción al tema en un artículo del 2006:
The ADO.NET Entity Framework Overview
Algunas características que aparecieron:
Entity Designer
- Generate a model from a database (via wizard) and display it on the designer surface
- Edit conceptual model properties (namespace, alias, etc.)
- Control visual aspects of the design surface (layout) and persist changes
- Add, Delete, and Edit Entities; Scalar properties; Associations; and Inheritance
- Automatic set management
- Automatic Navigation property management
- Error reporting
- Validate model and mappings using Entity Framework Runtime
Entity Mapping
- View the mapping for a C-Side Entity or Association
- Rename or delete C-Side objects without worrying about mapping
- Map an EntityType to multiple tables
- Apply multiple conditions to a table mapping
- Map associations
- Automatic generation of conditions and referential constraints on associations
- TPH: Map an Entity hierarchy to a single table
- TPT: Map an Entity hierarchy to multiple tables
Entity Model Browser
- Understand and visualize the model in a tree hierarchy
- Visually relate shapes on the designer surface with hierarchy in model
Visual Studio Integration
- Support for C# and VB in multiple project types: ASP.NET Web site, ASP.NET Web Application Project, Console, WinForms, and Library
- Project system integration: item template for .edmx file, model generation wizard, EdmxDeploy.exe, and Entity Framework validation on build
- Support for multiple Visual Studio editions: Express, Standard, Pro, and VSTS.
Gracias a Paulo Arancibia por el aviso, y a Martín Salías por algunos detalles de providers.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Ayer recibí desde varias fuentes, este enlace:
http://www.microsoft.com/opensource
Ya había escrito sobre Open Source en Microsoft. Ahora aparece este nuevo subsitio en el gigante sitio de MS. Veremos qué nos ofrecerá en el tiempo. En principio, es una nueva adopción de las palabras Open Source para alguien como MS que durante años sólo admitía un Shared Source. De alguna forma, este nuevo subsitio pone algun contexto, pero creo que lo más importante hasta ahora, para el tema Open Source desde MS, ha sido la creación y mantenimiento de Codeplex. No olvidemos Port25 (aunque más orientado al ambiente no Microsoft).
Leemos a Bill Hilf en Open Source at Microsoft:
Today, Microsoft took another step in its relationship with the open source software community. We did this by bringing up a new web property that clearly outlines Microsoft’s position on OSS by providing specific information about Microsoft, the OSS community and the interaction between the two. The new site also details information about getting started with OSS and Microsoft technologies. We'll keep the site updated with new content featuring Microsoft’s engagements with the OSS community - be that events like OSCON, partnerships, offers or just interesting articles highlighting different work we're doing across the company. Port 25 will continue to be the source for technical analysis and community with the Open Source Software Lab.
Para más aclaraciones, visitar la FAQ:
http://www.microsoft.com/opensource/faq.mspx#
Pueden leer algunos artículos de Garret Serack sobre Open Source en Microsoft:
http://blogs.msdn.com/garretts/archive/tags/Microsoft/default.aspx
También a Sam Ramji en
http://port25.technet.com/archive/tags/Sam+Ramji/default.aspx
Pero insisto: como desarrolladores, lo más interesante hasta ahora, ha sido y sigue siendo Codeplex. Tengo que activar un poco el movimiento de AjGenesis en Codeplex (como publicar un release directamente ahí).
Gracias a Martin Salias, Ramiro Iturregui, y Ezequiel Jadib, por avisarme de este subsitio.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Gracias a la organización del Microsoft User Group de Argentina, habrá una reunión gratuita de arquitectura en Buenos Aires, dedicada a presentar el proyecto de código abierto AjGenesis. Ver detalles de inscripción en
http://www.mug.org.ar/Eventos/2767.aspx
Ya escribí sobre generación de código en este blog, y sobre AjGenesis:
Sobre la generación de código
Generando aplicaciones con AjGenesis
Generando Código- Hello World con AjGenesis
AjGenesis está escrito en .NET, y puede ser manejado independientemente o integrado a otra solución. Permite generar, desde un modelo libre, y mediantes plantillas y tareas definibles, los artefactos de textos que necesitemos. Se mostrarán los fundamentos de la generación de código, y ejemplos que arman soluciones con ASP.NET 1.x/2.x, VB.NET, C#, o Java, JSP, PHP, con scripts de base de datos, y elementos de arquitectura, como Business Components/Business Entities, o elementos de modelo de dominio a la Evans, como Entities, Services. Se genera persistencia usando ADO.NET, Hibernate, NHibernate, JDBC.
Los que me conocen, saben que me entusiasma el tema. No sólo el proyecto, sino las posibilidades de la generación de código en general. Espero que "vean la luz"... :-)
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Al fin está disponible la película en Internet:
http://video.google.com/videoplay?docid=-7039094381603369679
(comienzo de la película, donde se muestra la filmación de un famoso aviso de Apple, "1984") (Gracias a Johnny Halife por el dato)
Yo, como siempre, prefiero el libro, "Fire in the valley". Ese libro me alimentó durante casi dos décadas, y siempre vuelvo a él a investigar algun tema. Lo veo más detallado que la película, y tal vez, más imparcial, a pesar de estar más cerca de los hechos. Lo interesante de la película es que nos sumerge mejor en algunos ambientes, para nosotros que no lo vivimos (el ambiente de los 70, 80 en EEUU). Igualmente hay que verla con alguna actitud crítica. Habría tanto para comentar sobre los detalles de la historia de la microinformática. Desde la influencia de Popular Mechanics, los clubes de entusiastas, y los aficionados que viajaban medio EEUU para llegar a la sede del MITS para comprar la primera Altair.
Grande recordar a Ballmer jugando póker con Gates, o al Capitán Crunch (luego contratado por IBM para escribir uno de los primeros procesadores de palabras de la IBM PC)... :-)
Era un tiempo, donde el mundo humana estaba cambiando... Sigue cambiando, ¿somos parte de ese cambio?
Que la disfruten, nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Software Fortresses (podríamos traducirlo Fortalezas de Software), es el libro más conocido de Roger Sessions, del que pueden conocer más visitando su sitio:
http://www.objectwatch.com
en especial sus "white papers"
http://www.objectwatch.com/white_papers.htm
(el de junio de 2003 es el más cercano al libro que vamos a discutir). Publica la ObjecWatch Newsletter, que en el tiempo de publicación del libro (año 2003) era recibida por correo electrónico por más de 20000 suscriptores.
Roger Sessions es un experto en arquitecturas de software de empresa, y el creador del modelo presentado en el libro, el modelo Software Fortress. Veamos un resumen de lo que quiere presentarnos.
Es interesante el prefacio, donde Sessions le pregunta al lector, presunto arquitecto, cuál es la arquitectura del software que tiene armada en la empresa. Se imagina que recibe como respuesta una arquitectura en 3 o n-capas, totalmente ordenada y pensada. Contesta: "Mientes, yo sé cuál es tu arquitectura". Y pasa a imaginar un "mess", una mezcla de servidores, bases de datos, aplicaciones web, atadas con alambre diríamos en Argentina, que apenas se sostiene, y que fue creciendo con el tiempo, de forma caótica.
De ahí en más, se dedica presentarnos su modelo.
Un cuestionario que presenta en el capítulo 1, hace un relevo de la situación del lector:
1. Su compañía tiene docenas de sistemas desarrollados independientemente, algunos armados, otros comprados, otros adquiridos por fusiones con otras empresa. Y algunos, no sabe de dónde vinieron.
2. Sus sistemas están interrelacionados de una forma tan compleja, que no puede predecir las consecuencias de un cambio o las ramificaciones de una posible falla.
3. Tiene discusiones "religiosas" sobre tecnología. Que Java sí, que .NET no. Ninguna de las dos partes se comunica bien con la otra.
4. Los departamentos de su compañía no confían en los datos del otro, así que duplican esfuerzo y trabajo.
5. Las bases de datos están hechas una mezcolanza de datos. Cada departamento tiene sus propios datos, sus propios administradores de bases de datos, y sus propias ideas de cómo manejar la seguridad de esos datos.
6. Su compañía tiene miedo de conectarse a Internet. Tienen información de misión crítica y privada que no quieren exponer o comprometer hacia afuera.
7. Tiene sistemas "legacy" de los que dependen, pero tiene miedo de cambiarlos. Algunos no los cambia por lo frágiles que son, otros porque fueron construídos por empresas que ya no están en el mercado, o porque el desarrollador original pasó a mejor vida, y hasta de algunos no tiene el código fuente.
Si contesta SI a por lo menos 5 de estas preguntas, felicitaciones, no está solo, y éste es su libro.
Algunas definiciones
Definition: Software Fortress
A software fortress is a conglomerate of software systems serving a common purpose and typically owned by a cohesive group of individuals. These software systems work together in a tight trust relantionship to provide consistent and meaninful functionality to a hostile outside world.
Esto incluye detalles técnicos y organizacionales. Desde el punto de vista técnico, una fortaleza de software es un conjunto de sistemas, que pueden ser procesos, servicios, componentes de lógica de negocio, bases de datos.
Desde el punto de vista organizacional, la fortaleza de software agrupa a las personas que trabajan juntas, que tienen un razonable conocimiento de qué está trabajando cada uno, tienen confianza en los sistemas que arman y operan. Es un pequeño departamento de IT dentro de la empresa.
Sessions comienza entonces a desarrollar la idea que el software de una empresa debe organizarse conectando estas fortalezas de software. Adopta una serie de íconos para representar a las fortalezas, y los elementos que pueden adosárseles, para tener un dibujo, una diagrama entendible que describa cada fortaleza.
El libro se dedica a la parte técnica de esos elementos, y lo que Sessions y cía, han descubierto o proponen, como elementos de las distintas fortalezas.
Definition: Software Fortress Architecture
A software fortress architecture is an enterprise architecture consisting of a series of self-contained, mutually suspicios, marginally cooperating software fortresses interacting through carefully crafted and meticulously managed treaty relantionships.
Definition: Software Fortress Model
The software fortress model is a methodology consisting of specific algorithms, categories of technologies, and documentation techniques that together can be used to model and build enterprise systems as software fortress architectures.
Un diagrama de ejemplo de fortaleza:
Algunos de los elementos propuestos, cada uno de los cuales tiene su ícono:
- Las paredes (walls) de una fortaleza están diseñadas para prevenir cualquier comunicación con el exterior, a menos que pase por los canales aprobados
- Los canales apropiados son los puentes levadizos (drawbridges) y son vigilados por guardias (guards).
- Los diplomáticos (envoys) preparan la comunicación entre fortalezas.
- Un baúl de datos (data strongbox) representa la colección de datos persistidos que se usan dentro de la fortaleza.
De ahí en más, Sessions va describiendo cada uno de estos elementos, metafóricos, trasladados a tecnologías, explicando las implementaciones y la razón de ser de cada elemento.
Los íconos que se colocan dentro de cada fortaleza, los llama trabajadores (workers). Utiliza una librería de gráficos:
http://www.novadevelopment.com/Products/us/aqw/default.aspx
donde aparecen vikingos, guardias, hadas, dinosaurios (representan sistemas "legacy"), brujos, y directores de orquesta, cada uno de los cuales va adosado a un concepto de Sessions.
Algunos tipos de fortalezas
Business application fortress (BAF), donde corre el negocio. Por ejemplo, el control de inventario.
Treaty management fortress (TMF) que maneja la relación con otras fortalezas
Legacy fortress (LF) con un dinosaurio dentro, representando alguna aplicación antigua.
Presentation fortress (PF) representadas por un caballete de pintor, típica para un servidor o granja de servidores web.
Web service fortress (WSF) representadas por un mago, son responsables de atender pedidos de funciones vía Internet.
Service fortress (SF) es una de sus últimas adiciones al modelo, representadas por un hada, provee servicios a otras fortalezas.
Algunas fortalezas pueden tener varios íconos dentro.
Lo nuevo de Sessions, es presentar todos estos elementos en fortalezas. Propone que todos los sistemas, en vez de estar conectados de forma difuso, se organicen en fortalezas, donde los puntos de entrada, la seguridad, lo que exponen y consumen, está específicamente determinado por los puntos de entradas (puentes levadizos), guardias, y demás elementos. Esa es la "vuelta de tuerca" que propone. Pueden ver más detalle en el libro o en "paper" mencionado más arriba.
Resumen de los capítulos
Capítulo 2: Diagramming Software Fortresses
Presenta en más detalle los diagramas, algunos instrumentos de texto como la declaración de un tratado, y los tipos de fortaleza más frecuentes y sus documentos asociados.
Capítulo 3: Transactions
Explicita el tema tan importante de transacciones, explica qué son los recursos "trancsactionally aware", que participan de transacciones. Si los recursos a participar de una trasacción se encuentran separados, aparece la figura del Distributed Transaction Coordinator (DTC).
Capítulo 4: Drawbridges
Son las tuberías por las que fluye la información de fortaleza a fortaleza. Es un punto de entrada definido a una fortaleza. Intervienen los diplomáticos para preparar el mensaje, los guardias para ver de dejar entrar un mensaje o no. Luego discute distintas tecnologías, como sobres SOAP, COM+, Enterprise JavaBeans, que pueden usarse como base de estos puentes de comunicación. Como tema importante, lo subdivide en los dos siguientes capítulos.
Capítulo 5: Synchronous Drawbridges
Es un canal donde el que llama espera una respuesta inmediata, como si fuera un llamada a función. Sessions destaca que la tecnología de puentes sincrónicos se basa en componentes. Hay un "objeto" (no necesariamente un objeto, pero es frecuente) remoto que expone una interfaz, y se ve opaco desde el cliente. Plantea el problema de que históricamente, surgieron tecnologías homogéneas, que sólo permiten comunicar dos partes de la misma tecnología, pero en los últimos años surgieron, ante la necesidad de interoperabilidad, las tecnologías heterogéneas. Se deben resolver problemas como la seguridad automática (el cliente debe "aparecer" de alguna forma en el servidor llamado), manejo de instancias (cuándo un componente nace, y cuándo se libera) y el flujo de transacciones (cuándo una transacción aparece, y se expande, y cuándo viene distribuida).
Capítulo 6: Asynchronous Drawbridges
En situaciones donde el mensaje enviado no necesita una respuesta inmediata, se pueden usar puentes asincrónicos, donde la respuesta puede venir mucho más adelante en el tiempo. Acá, históricamente se han implementado con colas de mensajería. Se discute el tema transacciones en las colas, la persistencia de los mensajes, y la posibilidad de que el mensaje tenga varios destinatarios. De nuevo aparece el problema de puentes homogéneos y heterogéneos.
Capítulo 7: Guards and Walls
Las paredes impiden el acceso a la fortaleza. Los guardias lo permiten. El arquitecto de la fortaleza es responsable de ver cuán selectivo será un guardia y qué tecnologías se usarán para implementar esa selectividad. Se discuten los temas de: fortificación, validación, auditoría, autenticación, privacía, integridad, no repudiación, autorización.
Fortificación se refiere a la habilidad de la fortaleza de prevenir la entrada a la misma, excepto a través de los puentes.
Validación es el control y recontrol de las entradas provistas por el exterior o el usuario.
Auditoría es la habilidad de trazar todos los cambios al estado interno de la fortaleza.
Autenticación es el procedimiento que se usa para convencer al guardia de quién está tratando de acceder.
Privacía es la capacidad de enviar información de tal manera que no pueda ser leída por usuarios no autorizados.
Integridad se asegura que la información en ruta no sea cambiada.
No repudiación se refiere a la capacidad de probar más adelante en el tiempo que tal informacion vino de tal origen.
Autorización es la habilidad de determinar, en base a la información que viene en el pedido (no según la fortaleza que lo pide) si su ejecución pedido puede ser permitida.
Capítulo 8: Treaties
Son los tratados, acuerdos formales entre fortalezas que definen cómo trabajaran entre ellas.
Capítulo 9: General Fortress Issues
Se tratan temas como escalabilidad. Una fortaleza es escalable si su unidad de costo de atender un pedido, es lo suficientemente baja para no perder una ganancia. Si cada pedido implica una pérdida, debería acotarse la cantidad de pedidos a atender. Otra condición para la escalabilidad es que podamos incrementar la carga de trabajo de un proceso, ya sea con mejores servidores (scale-up) o agregando servidores (scale-out).
Otro tema es la "reliability", la confianza que tenemos en poder contar con la fortaleza cuando la necesitemos. Y finalmente, la integridad. Una fortaleza es diseñada para proveer una alta integridad si no hay nada que la dañe o la deje en un estado incompleto, aún ante el fallo de otras fortalezas.
Capítulo 10: Internet Fortresses
El tema Internet merece un capítulo aparte. Las fortalezas de presentación y de servicios web pueden ser expuestas, por ejemplo, en una zona desmilitarizada, y comunicarse de formas específicas con el resto de la empresa. Se discuten tecnologías como ASP, JSP, ASP.NET, el tema de la escalibidad (con un cluster, por ejemplo, scale-out), seguridad, como el uso de firewalls, zonas desmilitarizadas, usar servidores de presentación con sólo algunas características activadas; disponibilidad, integridad, y las tecnologías de servicios web, con los mismos temas.
Capítulo 11: Business Application Fortresses
Son el pan y manteca de la empresa. Son los que "hacen el dinero". Son los procesos de contabilidad, las compras, ventas. Merecen nuestro respeto y gratitud. Se discuten componentes, manejo de estado, fronteras de transacciones y su manejo, el apalancamiento de "clusters", Java vs .NET, y hasta el costo.
Capítulo 12: Legacy, Service, and Treaty Management Fortresses
Un capítulo con varios temas. Por un lado, los sistemas "legacy". Aparecen los servicios, como por ejemplo, el "broadcast service", cómo un "publisher" envía un mensaje a varios suscriptores. Las fortalezas de manejo de tratados manejan las relaciones complejas entre tres o más fortalezas.
Capítulo 13: Software Fortress Design Review
Presenta 25 preguntas que se deben realizar durante el diseño de una solución de fortalezas de software. Son tres grupos: para gerentes de nivel empresarial, para arquitectos de nivel empresarial, y para arquitectos y diseñadores de fortalezas individuales.
Capítulo 14: Case Study
Finalmente, se presenta un caso de estudio, una empresa que vende por Internet. Se plantea el uso de iteraciones en el desarrollo, en este caso se usan dos. Se usan documentos para analizar la complejidad de la arquitectura a armar.
Capítulo 15: Postlude
Presenta diez puntos importantes sobre fortalezas de software, y diez puntos para adoptar el modelo Sessions, más diez reglas para su diseño, y diez ideas controversiales del modelo (como poner en segundo lugar el rendimiento, y que los guardias son los encargados de la seguridad, y luego en la fortaleza se puede hacer lo que se quiera). Aparecen diez consideraciones para evaluar J2EE vs .NET, como si necesita o no ejecutar en un ambiente no Windows. Y diez observaciones sobre el estado de la industria del software, notablemente una: la industria del software no tiene un modelo conceptual para construir sistemas empresariales.
Se agradece al final la presencia de un glosario, que nos permite entender cada término presentado.
Conclusión
Es un libro para leer, y sacar algunas ideas. No todos tenemos que lidiar con todos los problemas presentados, pero me gusta el libro porque presenta eso: problemas. Luego, abstraidos de las soluciones tecnológicas, son mejor entendidos. Creo que muchos estudiamos tecnologías, sin tener en claro cuáles son los problemas que solucionan, y las razones, las causas de la aparición de esos problemas. Los conceptos de Sessions permiten tener claro esos temas, y luego, como adicional, menciona y describe las capacidades de las tecnologías disponibles para resolver esos problemas. Es un libro para aclarar la mente.
Gracias a la biblioteca de SouthWorks, pude leerlo y comentarlo acá.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
En el post Sobre generación de código he recibido varios comentarios. Gracias a todos, por aportar algo y comentar. Uno de los comentarios, es de Jorge Ubeda. Recomendaría visitar su blog:
Hacia la cuarta generación del software
donde tiene varios artículos sobre los temas de Domain Specific Languages, MDA, MDD, y demás. En especial, su tags sobre DSL, MDA...:
DSL
MDA
Modelado
Vean también los blogs recomendados por Jorge, un ejemplo:
http://www.fabricadesoftware.cl/
En el comentario que me dejó Jorge, escribía:
SQL un DSL? no me parece atinado su uso por Microsoft como un ejemplo de un Domain Specifc Language, al menos si se propone que estos sean construíbles. Con este criterio DSL es un éxito total, vivimos rodeados de DSLs (podríamos llamar así a Visual Fox o semejantes), y no atendemos su uso propuesto actual.
En mi post, ponía como DSL al lenguaje SQL. Quería aclarar que en ese post lo uso a mi manera y parecer, aunque parece ser es la posición de Microsoft. Pueden ver algo de lo que propone esta empresa como herramientas para DSL:
Domain-Specific Language Tools
Pero veamos alguna definición de DSL. En el artículo de Jorge:
DSL: Una bibliografía anotada
encontramos una definición:
A domain-specific language (DSL) is a small, usually declarative, language that offers expressive power focused on a particular problem domain. In many cases, DSL programs are translated to calls to a common subroutine library and the DSL can be viewed as a means to hide the details of that library
Por lo menos es un lenguaje declarativo, dedicado a un dominio en particular. En otro artículo de Jorge:
Cuál es el alcance real de los lenguajes de dominio (DSL)-
encontramos finalmente de dónde viene la idea de SQL como DSL, de una presentación de Microsoft:
Think of a DSL as a small, highly focused language for solving some clearly identifiable problem that an analyst, architect, developer, tester, or system administrator must wrestle with. Developers are already familiar with examples of DSLs; SQL for data manipulation, XSD for XML document structure definition, and so on.
Creo que es válido considerar al SQL como un lenguaje específico de dominio. Es bastante declarativo (le pedimos select * from employee, él "decide" luego cómo llevar a cabo esa operación), y está orientado a un dominio (recuperación y actualización de datos relacionales).
Jorge menciona también dos artículos clásicos, de Martin Fowler:
Languages Workbenches- the killer-app for Domain Specific Languages-
Languages Workbenches and Model Driven Architecture
que "debe ser leidos".
Habria tanto para comentar, por ahora suficiente por hoy. Más adelante comentaré sobre MDA, MDD, otros generadores de código (sí, hay vida más allá del AjGenesis...;-), y algún proyecto como AndroMDA.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Hay multitud de este tipo de ejemplos en la web, pero quería comentar un ejemplo en Visual Basic .NET, y sin usar archivos de configuración, para ir explicando y entendiendo, algunos conceptos de Windows Communication Foundation. El código del proyecto se puede bajar de WCFHelloWorld1.zip.
Recursos, explicaciones en inglés, ejemplos y el propio .NET 3.0 están disponibles desde:
http://wcf.netfx3.com/
http://www.netfx3.com/
La solución de este "post" de ejemplo consta de tres proyectos:
Todos los proyectos referencian a una nueva DLL .NET que contiene la implementación de System.ServiceModel:
Hay un proyecto consola de cliente, y otro proyecto consola con el servidor. El tercer proyecto, es una librería que define el contrato:
1 Imports System
2 Imports System.ServiceModel
3 Imports System.Runtime.Serialization
4
5 <ServiceContract()> _
6 Public Interface IHelloWorld
7 <OperationContract()> _
8 Function HelloWorld(ByVal name As String) As String
9 End Interface
10
11
Vemos que el contrato es una interfaz, y está adornada con el atributo ServiceContract. Cada operación de la interfaz que queremos exponer dentro del servicio WCF, deberá tener el atributo OperationContract.
El programa cliente referencia a esta librería, y por eso, conoce esta interfaz (en otros ejemplos, el cliente puede agregar una referencia a un servicio, y el generador de código del proxy cliente, construye la interfaz, pero en este ejemplo quería ir armando la relación programáticamente).
El programa servidor tiene una implementación, una clase que implementa la interfaz de servicio:
1 Imports WCFHelloWorldLibrary
2
3 Public Class HelloWorldService
4 Implements IHelloWorld
5
6 Public Function HelloWorld(ByVal name As String) As String Implements WCFHelloWorldLibrary.IHelloWorld.HelloWorld
7 Return "Hello " & name
8 End Function
9 End Class
10
El programa servidor, un programa de consola:
1 Imports System
2 Imports System.ServiceModel
3
4 Imports WCFHelloWorldLibrary
5
6 Module HelloWorldHost
7
8 Sub Main()
9 Dim host As ServiceHost = Nothing
10 ' Consider putting the baseAddress in the configuration system
11 ' and getting it here with AppSettings
12 Dim baseAddress As Uri = New Uri("http://localhost:8080/WCFHelloWorldHost")
13
14 ' Instantiate a new ServiceHOst
15 host = New ServiceHost(GetType(HelloWorldService), baseAddress)
16 Dim binding As New BasicHttpBinding()
17
18 host.AddServiceEndpoint(GetType(IHelloWorld), binding, "/HelloWorld")
19
20 host.Open()
21
22 Console.WriteLine("Press enter to end")
23 Console.ReadLine()
24
25 host.Close()
26 End Sub
27
28 End Module
29
El tipo ServiceHost es parte de System.ServiceModel, lo nuevo de .NET 3.0 que implementa Windows Communication Foundation. Es la clase que permite exponer una implementación de un servicio, en este caso, objetos del tipo HelloWorldService.
En el constructor del ServiceHost se puso el tipo que albergará, y la dirección donde se expondrá. Ahora bien, un servidor puede exponer la misma implementación, en distintos service endpoints. Cada service endpoint puede indicar lo que se llama un binding, y un nombre. Eso se agregó en la línea 18. En la línea 16 se definió que el binding será basado en HTTP básico (hay bindings más poderosos en WCF, como uno que implementa las últimas definiciones de la especificación de servicios web, puede probar también WSHttpBinding, WSDualHttpBinding, y aparecerán más en la historia de WCF). El primer parámetro de la llamada de la línea 18 es el contrato: la interfaz IHelloWorld que ya habíamos definido.
Con esos datos, el cliente puede invocar a nuestro servidor:
1 Imports System
2 Imports System.ServiceModel
3 Imports WCFHelloWorldLibrary
4
5 Module HelloWorldClient
6
7 Sub Main()
8 Dim cf As New ChannelFactory(Of IHelloWorld)(New BasicHttpBinding(), New EndpointAddress("http://localhost:8080/WCFHelloWorldHost/HelloWorld"))
9 Dim service As IHelloWorld = cf.CreateChannel()
10 Console.WriteLine(service.HelloWorld("Adam"))
11 Console.WriteLine("Press enter to end")
12 Console.ReadLine()
13 End Sub
14
15 End Module
16
En este cliente, se usó una clase ChannelFactory, que usa generics, y necesita que le pasemos el tipo a implementar. La factoría de canales tiene el gran método CreateChannel que devuelve un objeto que construye en el momento, que es un proxy, un objeto en el cliente, que implementa automáticamente el tipo que le pasamos como parámetro a la factoría, en este caso, un IHelloWorld. Esa es la "magia" de la factoría: analizando el tipo, implementa con generación de código (creo que usando CodeDom), todo el proxy que por debajo invocará al servidor. Dos parámetros que necesita la ChannelFactory en su construcción son el binding, y la dirección del endpoint (vemos que ésta incluye el nombre /HelloWorld). Tanto la dirección como el binding deben coincidir con el que está definido en el servidor. Pero recordemos: el servidor puede haber expuesto una implementación, con varias direcciones de endpoint y otros bindings.
Lanzamos ambos proyectos (el cliente y el servidor), ya sea configurando la solución para que lance ambos, o lanzando cada uno para depurar, o luego de armar la solución, los podemos lanzar cada uno desde una línea de comando.
Lo importante es comprender:
- El cliente sólo necesita la interfaz, el contrato, y dónde ubicar al servidor
- El servidor levanta un objeto que expone nuestra implementación, usando una dirección, binding, y contrato
Veremos más adelante que podemos implementar cómo levanta el servicio, y cómo se lo referencia en el cliente, mediante sendos archivos de configuración en ambos proyectos.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
Ya en algún "post" anterior, Generando aplicaciones con AjGenesis comenté sobre cómo el proyecto AjGenesis genera código para distintas plataformas, incluyendo VB.Net 1/2, C# 1/2, y usando ADO.NET o NHibernate. El proyecto está basado en templates, que cualquier puede adaptar para generar como quieran los artefactos de texto que necesiten, en cualquier tecnología. AjGenesis está escrito en VB.Net, y es un proyecto de código abierto.
Gracias a la lectura de otro "post", Sobre la generación de código, surgió una iniciativa de Omar del valle Rodríguez, para generar un modelo que le interesa, en NHibernate. Pueden ver el thread original en la excelente lista de arquitectura del Microsoft User Group de Argentina:
http://www.mail-archive.com/arquitectura@mug.org.ar/msg00349.html
(me temo que no quedaron aún publicadas las respuestas al mensajes, entre ellas la propuesta del bueno de Omar).
La idea de Omar es implementar, según sus propias palabras:
"Una empresa, cuyos clientes pueden ser personas o empresas, los clientes se deben tratar como tal, independientemente de si es persona o empresa, pero deberíamos poder identificar a cada uno por separado..
En el resultado que espero siempre veo que se genere: 3 tablas, cliente, persona y empresa, con una relación uno a uno entre ellas partiendo de cliente.. y en el modelo sería un objeto cliente del cual heredan persona y empresa."
Bien, interesante modelo. Me llevará a implementar por primera vez, en mis modelos (recuerden que el modelo del AjGenesis ES LIBRE, cualquiera puede armar el modelo que quiera), entidades con generalización. Aquí Cliente será la generalización de Persona y Empresa. Según lo pedido por Omar, habrá tres tablas: una donde estan los datos de todos los Clientes, otra donde estarán los datos adicionales de una Persona, y otra para los datos específicos de Empresa.
Luego, en la discusión del tema, llegamos a tener como objetivo a generar, de nuevo, en palabras de Omar:
1- Client.hbm.xml (archivo de mapeo para NH)
2- Client.cs (entidad en C# que describe un cliente)
3- User.cs (entidad en C# que describe un cliente de tipo "persona")
4- Company.cs (entidad en C# que describe un cliente de tipo "empresa")
5- ClientFactory.cs (Factory que me permite manipular una entidad Cliente [Insert, Update, Delete, GetAll, GetByID, GetAllCompany, etc, etc])
6- Client.sql (script para SQL Server con el código de las tablas a incluir)
Además, podríamos generar el código para VB.Net, y algunas páginas ASP.NET para navegar y actualizar las entidades del modelo, como hacen los anteriores ejemplos de AjGenesis. Omar proveerá una implementación destino, y armaremos el modelo, los templates y tareas en AjGenesis, para producir esos archivos y algo más.
El problema está planteado. Veremos cómo progresa, en nuevos artículos.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com/
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, "frameworks" 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.
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.... ;-)
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 "Lograría su cometido si complaciera aunque sólo sea a un lector que lo comprenda". Espero no ser tan oscuro como el joven Ludwig, y que algo de lo que escriba se entienda y sirva a alguien.
El tema me importa: espero que se note.
Todo cambia
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 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á "the ultimate solution", 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.
La complejidad
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.
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ó.
No somos vulcanos
¿Recuerdan al Señor Spock, de Viaje 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 "manejar" 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 "divide y vencerás". 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 "infame" construcción ocurrió a nivel humano, a nivel de los lenguajes que manejamos, los procesadores ni se enteraron del problema).
Cada año que pasa, es más evidente que necesitamos ayuda para construcción de software. No podemos solos.
Software que genera software
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 "dog fooding": comer la comida del perro, usar las propias herramientas, para apreciar las ventajas y limitaciones de lo que producimos.
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.
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.
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.
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.
Creando sistemas con tecnologías
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 "proficient", 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.
Eso que hicimos por años se puede resumir:
- 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...)
- 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...)
- Cuando tenemos un nuevo sistema, nos basamos en lo que ya construímos
Frameworks y librerías
Próximo paso que algunos dimos: luego de haber resuelto los puntos del párrafo anterior, se nos ocurre:
- Armar una librería de clases, que resuelvan lo que hacemos repetitivamente en cada sistema
- 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, o cualquier otro, que alguien haya hecho, para solucionar algunos temas que no queremos armar nosotros.
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.
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.
Arquitectura y patrones
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 "silver bullet", la bala de plata que mate todos los vampiros que amenazan todo nuestro esfuerzo de creación de software.
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.
De nuevo, tenemos soluciones, pero mucho trabajo.
Look ma, no code
Otra solución intentada, es generar pantallas, páginas, funcionalidad en "runtime", 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.
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 "on the fly" para JSP, y luego aparece JSF.
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.
Aprendiendo, aprendiendo
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.
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.
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.
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 "post" 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...;-)
Cabecitas, y más cabecitas
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.
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.
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.
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.
Herramientas y agentes
J.P.Plauger, mítico programador, creador de compiladores, empresas y libros, me llamó 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.
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 "software factory" 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 "post". Recuerden: podemos conseguir más que una herramiente, un agente. Algo más sobre "inteligencia artificial" más abajo.
Domain Specific Languages
Vimos que una estrategia, como la empleada en la compilación, implica:
- un lenguaje de alto nivel
- una herramienta que pase de ese lenguaje a algo que entienda la máquina
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.
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
select * from employee
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:
- No es genérico, es específico de un dominio
- Es flexible
- Hace lo que necesitamos hacer, por nosotros
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 "Hello, World", 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.
Algunos generadores de código
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.
Primero: el generador sólo genera lo que él quiere. Típico de generadores "profesionales", 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.
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.
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.
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.
El camino del demonio
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.
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.
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. "Forget it", XSLT caca.... ;-)
Hacia un generador de código
¿Qué le pediríamos entonces, a un generador de código? Gran pregunta, intentemos algunas respuestas:
- 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.
- 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.
- 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 "Hello, World" que se nos ocurra. Si una herramienta no puede obtener ese resultado, estamos en el horno.
- 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.
- 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.
Dunga dunga un ratito
De alguna forma, un generador de código ideal no estará atado a una tecnología. Siempre habrá alguna "better mousetrap", siempre alguien inventará alguna nueva forma de hacer algo, siempre habrá un ruso con insomnio, o un hindú sin novia, que no tiene otra cosa que hacer que crear algo nuevo, 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.
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 "dunga dunga": si aparece una nueva tecnología T1, le hacemos "dunga dunga" a T1, si aparece un nuevo framework PiruloStruts, adaptamos nuestras plantillas a aprovecharse de ese framework, "dunga dunga" 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.
Mi corazoncito
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 AjGenesis. Lo pueden bajar, probar, examinar, integrar, modificar, hagan lo que quieran. Pero no digan que no les mostré la luz... ;-) ;-)
Se basa en:
- Tener un modelo totalmente libre, que hoy está serializado en archivos XML.
- Plantillas que generan artefactos de texto
- 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.
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.
Pueden leer sobre el modelo libre que usa en:
Generando Código- Hello World con AjGenesis
(como el modelo está serializado en texto... adivinen... se puede generar desde el mismo generador!!!). Esto implica:
M1 (de alto nivel) ===> Templates+AjGenesis ==> M2 (de nivel medio) ==> Templates+AjGenesis ==> Mn..... ==> Artefactos de texto finales
¿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.
(Notablemente, ahora, muchos generadores de código más "profesionales", están adoptando esta estrategia: modelo libre.... vieron la luz... :-) ;-)
Pueden ver algunos ejemplos no triviales:
Generando aplicaciones con AjGenesis
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 M