Diego's profileZonaDiegumPhotosBlogListsMore Tools Help

Blog


    June 27

    Cuando un Mal Manejo de Excepciones Impacta en la Experiencia de Usuario

    boaerror
    Bank of America en calzoncillos

     El usuario ya se apioló de  que usan Java sobre IBM Websphere, que se quedan cortina de memoria, no escalan, etc. Un potencial hacker, al conocer la infraestructura en la que corre, si de paso conoce vulnerabilidades de la misma puede explotarlas en detrimento del banco y/o de sus clientes. Y eventualmente, además, en su propio beneficio.

    Ya había hablado de esto allá lejos por Septiembre de... 2005!! Ver Haciendo lugar a la Excepción.

    November 09

    PDC 2008. Architect's Cut

     Aunque, excepto algunas,  casi todas las sesiones del PDC 2008 están disponibles tanto online como offline (previo download, claro), uno puede sentir esa amarga frustración derivada de la abrumadora cantidad de las mismas

    Preguntas típicas que me hago yo mismo en esas situaciones emocionalmente encontradas son "Qué repositorio de info! Tendré tiempo de ver y posteriormente asimilar esta data!? Qué mirar primero? Qué si agarro alguna sesión que requiere ver otra antes, de modo de adquirir cierta base? Habrá alguna sesión que pudiera descartar sin sentirme culpable?"... y una larga lista de etcs

    Por suerte el equipo detrás del Microsoft Architecture Center (el Equipo de Arquitectura de Microsoft) está acá para ayudar: recorrimos la lista entera de sesiones, clasificandolas según complejidad, tópico abordado, relevancia en términos de arquitectura, etc, y extragimos una lista de unas 45 sesiones (la lista completa triplicaba o cuadruplicaba esto) que estamos actualmente exponiendo, pero en una forma gradual

     

    PDCforArcs

     

    Para estos días estamos exponiendo las que que consideramos "watchme.1st":

    • Guías de Diseño de Frameworks
    • Performance
    • Escalabilidad
    • Cloud Computing y Azure
    • El Modelo de Modelado "Oslo" (valga la redundancia smile_regular)
    • Lenguages Dinámicos
    • Caché Distribuido
    • Concurrencia y Paralelismo

     

     

    Vas a encontrar en estos días un video roller justo en la home page donde podrás seleccionar las sesiones de tu interés, click allí y, voilà!: el espectáculo comienza cuando Ud llega. No es necesario loguearse, nada

    Por supuesto, podés maximizar la ventana de video (me imagino que es lo que vas a hacer) gracias a la flamante tecnología Silverlight 2, o eventualmente visitar el sitio huesped (Channel 9) y descargar el powerpoint desde allí o, finalmente, una mezcla de todo

    October 27

    Guía de Arquitectura de Aplicación v2.0 - Beta 1 Liberada Recién

    PnP Application Architecture Guidance Mejor que  prometer cosas es ofrecer algunas realidades y esto es algo real

    Después del auspicioso éxito que la Guía de Arquitectura de Aplicación (versión 1.0) original había tenido, hubo una serie de libros en aspectos de sintonía fina tales como seguridad, rendimiento, escalabilidad, aspectos internos a los clientes inteligentes (smart client), aplicaciones web y otros

    Pero todo eso pasó entre el 2002 y el 2004 durante las oleadas de .NET 1.0 y 1.1. Y parte del feedback recibido fue posteriormente usado durante las etapas de maduración de .NET 2.0 sin embargo...

    Mientras que las mejores prácticas fueron saliendo de la agenda del arquitecto para aterrizar inherentemente en la plataforma de desarrollo (algo conocido como fase de comoditización), los arquitectos empezaban a quedarse con un sabor amargo en sus gargantas. Había muerto la Arquitectura con mayúsculas?

    La pregunta emergía una y otra vez

    MSDN Architecture Forums
    Foro de Arquitectura MSDN, tópico: va a pasar algo con la Guía de Diseño de Aplicaciones y Servicios?

    Hasta que finalmente el arquitecto de Patterns and Practices J.D. Meier tomó la posta y puso al motor de nuevo en marcha con su ahora legendario post "patterns & practices App Arch Guide 2.0 Project". J.D. comenzaba disculpándose en cierto modo: "It's long overdo..." ("es muy exagerado...")

    J.D. Meier's Blog

    Hoy, coincidiendo con la inauguración de sesiones en el PDC (la Conferencia de Desarrollo Profesional de Microsoft) en Los Angeles, la Beta 1 del proyecto fue liberada

    Application Architecture Guide 2.0 BETA 1

    Estuve echando un vistazo (en la medida en que me hago tiempo, soy a la vez contribuyente de este proyecto), y puedo garantizar al lector de esta guía que no es sólo una migración de .NET 1.0/1.1 a .NET 3.5 SP1 sino una redefinición completa de lo que Arquitectura de Aplicación significa hoy. Incluso más allá de la plataforma .NET, por qué no

    Este importante punto podría ser confirmado con sólo revisar cómo la información está organizada a lo largo del libro

    Information Architecture

    Tipos de aplicación, Estilos de Arquitectura, aspectos cruzados y un marco general de características que cualquier arquitectura debe tener en cuenta (más allá del tipo de aplicación soportado o del estilo que se siga como plano general)

    J.D. estimula al lector a descargar y aplicar estos recursos como si fuera la versión final de la guía, de manera de proveer feedback sea a través del motor de discusión de Codeplex (ver pestañas "Discussions" y "Issue Tracker"), o contando tus experiencias de dar vuelta el partido al haber usado esta guía a MyStory@Microsoft.com

    Es apenas la Beta 1 pero está sin dudas tomando forma. Sé parte del proyecto y ayudá a J.D. a hacer que la espera valga la pena! Open-mouthed

    September 30

    UML, Al Fin en Visual Studio (versión 2010, "Rosario")

    smile_omg   smile_secret   smile_party

    Semana Visual Studio 2010 en Channel9
    Semana Visual Studio 2010 en Channel9

     

    Camino a
    Camino a "Rosario"


    Peter Provost cuenta para nosotros (arquitectos) que viene en Visual Studio 2010
    Peter Provost cuenta para nosotros (arquitectos) que viene en Visual Studio 2010

    April 07

    Sistemas de Alto Rendimiento: la Carrera por la Computación Paralela

     Es  un hecho que hoy en día los equipos con dos procesadores son un estándar, y opcionalmente los hay de cuatro o más CPUs. Normalmente dos procesadores es la norma hoy en equipos cliente o "de escritorio" en tanto que más es norma para equipos servidores

    En estos casos se suele dar que las primeras aplicaciones que sacan provecho de estos avances son las de nivel más bajo como el sistema operativo o procesos servidores como el RDBMS (la base de datos, bah), etc

    En una segunda oleada estos beneficios pasan a ser dejados a disposición del público masivo, como ya pasara con los procesadores gráficos que al principio quedaban accesibles sólo a través de APIs especiales como DirectX y hoy cualquier mamerto con Windows Presentation Foundation pueden hacer aplicaciones que la gente diga "wow!" (lo de "cualquier mamerto" va por mí: el Architecture Journal Reader, canejo smile_shades jah!)

    Que al comienzo las APIs sean realmente complejas obedece a dos razones:

    • No están sus creadores lo suficientemente maduros en su entendimiento de las mismas como para poder ponerlo en términos más simples (para ello en realidad deben usarlas intensivamente de modo de extraer de esa experiencia las mejores prácticas), y
    • Como corolario de lo anterior, en cierto modo la idea es privar al público masivo de un acceso irrestricto hasta tanto no se vean formas de encapsular esos mejores usos en APIs que eviten provocar un malestar generalizado con estos avances

    Pero lógicamente, ya va llegando el momento y por ende la idea es poder brindar a las plataformas de desarrollo actuales de estas herramientas que allanen la curva de aprendizaje

    Asistimos en estos días a una carrera en el segmento de las plataformas administradas (tanto Java como .NET) para cumplimentar este objetivo. Para hacer honor al tema del post, Paralelismo y Concurrencia, voy a enlistar lo que .NET y Java están armando al respecto en forma paralela y concurrente (jeh, soy un piola yo... smile_tongue)

     

    .NET Framework

    Java Standard Edition

    • Se lanzó un portal MSDN para desarrolladores en Computación Paralela
    • El mismo tiene desde artículos introductorios, a contenido más específico al respecto (con ejemplos de código de lo que sería la futura API)
    • Esto va coronado con, para aquellos que quieran hacer pruebas de concepto (proofs of concept o PoCs) con un preview de PFX (o Parallel Extensions for the .NET framework) para extender sobre .NET 3.5 (lo que da a entender que esta facilidad, de liberarse, será para una versión seguramente posterior)
    • También hay videos, donde no puedo dejar de recomendar el realizado por Anders Hejlsberg, gurú de los lenguajes de programación y padre de Delphi y C#
    • Entre otras cosas, también se puede ver cómo PFX va a impactar en otras APIs existentes como LINQ (una API que facilita las consultas sobre colecciones de datos, sea que estos estén en memoria, en una tabla relacional, en un archivo XML o donde fuere). A esta unión lo he visto descripta como PLINQ (o Parallel LINQ, a mal entendedor muchas palabras smile_regular)
    • Para cuando la versión 5 de Java Standard Edition fue liberada (segunda mitad del 2004), una biblioteca (o paquete, y que me perdonen en Chile smile_embaressed) llamada java.util.concurrent permitía sacar provecho de equipos multiprocesador aunque en forma indirecta: esta biblioteca contenía componentes que hacían uso de esa característica para que los programadores consuman dichos componentes (no para que créen los propios)
    • El Requerimiento de Especificación en que el comité que evoluciona la plataforma trabajó fue el JSR-166, Utilidades de Concurrencia
    • Ese mismo JSR está ahora siendo revisado para incluir facilidades que permitan programación concurrente en Java 7 (estimado para principios del 2009)
    • La estrategia se basa en dotar a Java de técnicas Fork/Join con la filosofía de descomponer un algoritmo complejo en partes secuenciales más simples, y analizar de éstas cuales en verdad no dependen mutuamente sino de otras partes en común (pero no entre sí) de modo que puedan paralelizarse
    • A quien se lo ve muy activamente trabajando en esto es a IBM, quien a través de su portal DeveloperWorks ha publicado dos artículos al respecto

     

    Será hasta la próxima

    March 31

    Rol del Arquitecto: Reglas del Juego

     Una  de las principales razones por las que ha venido siendo tan dificil definir qué es un arquitecto es por la falta de acuerdo en cuanto a lo que un arquitecto debe hacer. Cómo distintas perspectivas le asignan a dicho rol distintas responsabilidades, por consiguiente el rol en sí mismo pasa a ser diferente según la perspectiva de donde se lo evalúe

    Esto me empezó a dar vueltas en la cabeza estos últimos meses, ya que con Simon estuvimos trabajando fuerte en el número 15 del Journal de Arquitectura, próximo a aparecer (*). El tema de este decimoquinto número es, justamente, el Rol del Arquitecto

    Como siempre hubo un call for papers (que tuvo lugar durante el pasado mes de Enero), y varias propuestas fueron recibidas, de las que escogimos unas siete u ocho. De estas seleccionadas fueron luego llegando los primeros borradores, por lo que puedo decir que me he pasado el trimestre que va terminando dando vueltas cuan pollo al spiedo alrededor del bendito rol que nos toca jugar

    Y lo que puedo anticipar de la edición que estás por recibir es que, como era de esperar, varios artículos se parecen entre sí en el sentido que hablan de un personaje con el que nos identificamos; pero al mismo tiempo discrepan entre sí, porque le atribuyen responsabilidades o conductas que nos puedan sonar cuestionables

    Entonces pensé que, como siempre, el origen de las divergencias se remonta a la clásica subdivisión del perfil de arquitecto en

    • Arquitecto Empresarial (o Estratégico)
    • Arquitecto de Desarrollo (o Soluciones)
    • Arquitecto de Infraestructura

    Yo asumo que esta subdivisión ya la manejás de taquito, pero si ése no es el caso, leéte este artículo de Simon que lo cuenta bastante claro

    La clasificación no está mala y, sobretodo, no es algo que un solo vendor impuso sino que hay no sólo un consenso en la industria: el framework de arquitectura conocido como TOGAF (The Open Group Architecture Framework) considera cuatro Dominios de Arquitectura (Architecture Domains). Estos son, a saber:

    Pero no termina acá, también la IEEE a finales de los '90 dio forma a su especificación IEEE 1471 (forma corta de referirse a Práctica Recomendada para la Descripción Arquitectónica de Sistemas de Software Intensivo), un estándar tanto ANSI como ISO. Esta especificación define Puntos de Vista (Viewpoints) nuevamente asignables a los roles antes descriptos

     

    Y sin embargo...

     

    Esta taxonomía está bien para organizar información relacionada con estos -tomando prestado de TOGAF- dominios de arquitectura antes descriptos. Pero no tengo claro que en la práctica necesariamente se dé que haya, en una misma organización, arquitectos cubriendo estos roles. No estoy diciendo que esté bien que sea así o que esté mal, sino que en la medida en que estos roles van madurando, las organizaciones ya venían lidiando a su modo con las necesidades a cubrir. Como resultado, tenemos que

    • Una misma persona cubre algunas actividades de uno o más roles, pero no todas las actividades que a ese rol le suelen asignar hoy los estándares
    • Un dado proyecto en una determinada organización puede requerir cierto nivel de cumplimiento con la definición de una arquitectura, pero a un nivel de detalle que puede resultar escaso según las normas de otra organización
    • Distintas organizaciones, partiendo de la base de que tienen distinto tamaño y diferente presupuesto de TI, lidian con distinto headcount (cargos a cubrir disponibles). Como resultado, las tareas de arquitectura a realizar se van a asignar al personal disponible (nuevamente conduciendo a que la relación entre roles y personas termine siendo cualquiera a cualquiera en lugar de 1:1, 1:n, m:n, etc

     

    Me siento lejos de la postura de decir que si en la práctica las cosas se dan así, es porque algo esté saliendo mal. Me ha tocado trabajar en proyectos donde ciertas decisiones que afectan a la arquitectura estaban ya tomadas (por ejemplo, plataforma J2EE contra base de datos Oracle sobre ambiente Linux, etc). Siendo esas las circunstancias, un arquitecto de infraestructura tenía poco margen de acción en cuanto a tomar decisiones de plataforma se tratase. Sin embargo, aún le cabía un rol preponderante en el despliegue de la solución (y la asignación de procesos a servidores, etc). No obstante, en los hechos, esta actividad de infraestructura terminó en más de un caso siendo cubierta por el "arquitecto" (así, en genérico) que era también el que diseñaba la solución a desarrollar. Obviamente que no cualquier arquitecto de soluciones podía estar ducho en la infraestructura elegida de antemano, como para definir la mejor manera de montar la solución, pero justamente eso era lo que hacía que ciertos proyectos atraigan a cierta gente que habría quedado al margen en otros proyectos que compartieran ciertas similitudes y ciertas diferencias (por ejemplo, plataforma .NET disparando transacciones vía Host Integration Server contra un CICS el que, a su vez, accede a una base de datos DB/2)

     

    Podríamos concluir que los roles oficiales tienen aparejados una serie de actividades, pero que en la práctica de ese menú total de actividades habrá algunas que van a ser cubiertas en forma total, otras parcialmente y aún otras ignoradas

    Estas actividades van a ser asignadas a diferentes arquitectos (en genérico) pero no necesariamente según rol sino considerando, en cada caso, el conocimiento que tengan del negocio y la cultura de la compañía, de la plataforma de desarrollo y de los ambientes de ejecución. En ese contexto, no va a ser descabellado aprovechar el expertise de un miembro del proyecto en -digamos- aplicar sintonía fina (fine tuning) a un esquema en Sybase, si bien su actividad principal sea la de definir y liderar el desarrollo de un framework de acceso a datos que encapsule la complejidad de APIs como JDBC o ADO.NET

    Será tarea del líder de proyecto, en base a las circunstancias actuales del mismo, definir qué actividades de arquitectura estarán presentes y en qué grado, y a quién/es serán las mismas asignadas

    ____________________________________
    (*) A propósito, desde el número 3 hasta el 14 (el actual) están disponibles en español

    February 24

    Qué Debemos Recordar Sobre la Pérdida de Memoria (Memory Leaks)

    Introducción: Pérdidas de Memoria en Java y .NET? Y el Garbage Collector? Funca mal? 

    Memory Leak Se  suponía que esta generación de lenguajes dentro del rango conocido como código administrado (managed code) iba a terminar con el dolor de cabeza que habíamos padecido los que -sea en Pascal como en C o C++ o cualquier otro lenguaje que permitía referenciar memoria a través de punteros (pointers)- tuvimos alguna vez que lidiar con manejo dinámico de memoria (esto es, pedirle memoria al sistema operativo y devolvérsela luego)

    Sin embargo me decido a escribir este post como respuesta a varias preguntas que he venido recibiendo de amigos que trabajan, sea con Java o con .NET, y que están padeciendo un problema que ellos pensaban que desde el vamos iba a estar superado

    Partamos por la definición: una pérdida de memoria (en inglés aparece como memory leak o fuga de memoria) es una situación que se produce cuando la aplicación no devuelve al sistema operativo franjas de memoria que ya tampoco va a usar. Generalmente con el agravante de que siendo que los datos en esa memoria son ya residuales, de necesitar espacio para nuevos datos, la aplicación va a pedir más memoria al sistema operativo al no considerar que tiene total o parcialmente espacio para alojar esta información

    Las pérdidas de memoria normalmente son procedurales. Es decir, la aplicación en la forma en que está programada, pierde memoria en forma sistemática de manera tal que nueva memoria solicitada al sistema operativo es también pasible de ser total o parcialmente perdida. De esta manera, dependiendo de la memoria original disponible, de la ocupada por procesos concurrentes, etc, siempre me alucino con la idea de que en algún momento el sistema operativo me saque una caja de diálogo como la siguiente

    Sin memoria

    La caja de diálogo de recién es una broma, claro. En cambio, lo que sí los sistemas operativos suelen hacer es asignar quantums de memoria a las diferentes aplicaciones, y aquellas que pasan cierto umbral de memoria requerida en un cierto tiempo son pasibles de ser penalizados por el sistema operativo, que puede comenzar por relegarlos a swappear ("intercambiar", del inglés swapping) su memoria entre almacenamientos primario y secundario, siguiendo por bajarles la prioridad de ejecución -para no pagar el mismo sistema operativo la penalización por swapping, ya que ese tiempo de intercambio se considera tiempo de ejecución del sistema operativo, no de la aplicación- hasta finalmente decirle a la aplicación su merecido "no va másssssss" como en la ruleta

    Esto último, los que programaron en Java lo recibieron en la forma de un java.lang.OutOfMemoryError, parecido al System.OutOfMemoryException de .NET -quiero destacar la riqueza expresiva de Java, que reconoce a los errores (java.lang.Error) como una categoría separada de las excepciones (java.lang.Exception); una excepción es eventualmente atajable (catch) en cambio un error implica un fallo fatal y la ejecución finaliza allí. Tal distinción no tiene paralelo en .NET-

    Ahora bien, las plataformas Java y .NET son entornos de ejecución administrados que cuentan con un recolector de basura (garbage collector). La idea del mismo -las implementaciones difieren algo- es detectar direcciones de memoria inalcanzables (por ejemplo, una variable local que se creo dentro de un bucle cuya ejecución ya quedó atrás; la variable es local al bucle y por consiguiente ya no hay forma de alcanzarla, ni siquiera definiendo otra variable con el mismo nombre o, si acaso, volviendo a ejecutar el bucle). A grosso modo, el recolector devolvería al sistema operativo esa memoria que venía siendo referenciada por variables que se quedaron fuera de scope aunque, en la práctica, a quien se la devuelve es a su propio montículo (heap) de memoria por si más adelante la fuera a necesitar. A su vez, sí, el montículo de la aplicación puede crecer o decrecer (pidiendo y liberando memoria al sistema operativo) pero en otros intervalos que los de la frecuencia del recolector

    Con esto dicho, el programador entonces no se entera de cómo la memoria es adquirida o devuelta por lo que si la aplicación toma ese recurso y luego no lo devuelve, todas las miradas se dirigen al entorno administrado (Java VIrtual Machine o JVM en la plataforma Java, Common Language Runtime o CLR en el caso de .NET). Y sin embargo, no: rebobinemos un poco la cinta hacia el párrafo anterior. Allí decía "la idea del recolector de basura es detectar direcciones de memoria inalcanzables"

    Ahí está el quid de la cuestión. En la medida en que instancias de objetos creadas sean alcanzables. Si los métodos que crearon estas instancias han devuelto referencias a las mismas, y a su vez dichas referencias fueron almacenadas como propiedades de otros objetos que son alcanzables, por transitividad las instancias creadas son también alcanzables. Ergo, si nuestras aplicaciones empiezan a dragar memoria en forma descontrolada, debo ser el portavoz de la mala noticia de que no vamos a poder irnos silbando bajito tan fácil Acá debo defender al gremio de los grandes distribuidores de plataforma: no es una falencia de la JVM o del CLR el no detectar que esta memoria de la que hablamos se debía haber liberado. Estos entornos de ejecución operan en una forma deterministica: es alcanzable, no se libera; no es alcanzable, se libera. Sin vueltas. El resto depende de nos, desarrolladores de software

    Escribo esto y me viene a la memoria la típica reacción que he visto en desarrolladores cuando sienten que la aplicación no libera memoria en la proporción que esperarían: forzar la llamada al recolector de basura. Esto al menos en la plataforma .NET no va a sino empeorar las cosas, como voy a mostrar a continuación

     

    Cómo Trabaja el Recolector de Basura

    La memoria de una aplicación .NET está organizada en varios segmentos. Uno de ellos, particularmente, es el llamado "segmento de memoria administrada" que es aquella que es reservada y liberada directamente por el CLR (en contraposición a otros segmentos, como el de "memoria primitiva" o "no administrada" que es el segmento de la memoria que el mismo CLR reserva para sí -la que él necesita para ejecutar nuestra y otras aplicaciones- y también aquella memoria que nuestra aplicación reserva en forma directa, por ejemplo en C++ o C#, mediante llamadas explícitas al sistema operativo). Pero volvamos al que nos interesa, el segmento de memoria administrada:

    En el mismo, a su vez, el montículo se organiza en generaciones. Esto es, por diseño, el CLR asume que si un objeto sobrevivió un determinado período de tiempo, entonces es probable que sobreviva por algún tiempo más. De esta manera, cualquier nuevo objeto que es creado se dice que pertenece a la generación 0, cuyo tiempo de vida se presume limitado. Entonces en un dado momento el CLR se va a encontrar con que el montículo no tiene memoria suficiente contigua para el siguiente comando new. Como consecuencia el hilo del recolector de basura se va a despertar y va a buscar en la generación 0 aquellos objetos que ya no sean alcanzables por la aplicación (variables fuera de scope, etc, lo que te contaba antes). La memoria ocupada por esos objetos no alcanzables es desasignada y todo el segmento de esta generación es compactado. Pero los sobrevivientes son inmediatamente movidos al segmento de la generación 1, por esto que te decía que el CLR presume que si zafaron es porque van a vivir un tiempo más. La generación 1 es también recolectada, pero sólo si tratar de liberar memoria en la generación 0 no produjo lo suficiente. Aún así, cuando haya recolección en la generación 1, la memoria de objetos no alcanzables será -nuevamente- desasignada y los que sobrevivan se asumirá que pueden llegar a durar un tiempo más por lo que serán movidos a la generación 2. Podríamos decir "y así sucesivamente" pero no: no hay más generaciones que la 0, la 1 y la 2. La generación 2 tiene la frecuencia de recolección más baja (sólo si recolectar en las generaciones previas no consiguió lo suficiente) y para los objetos que zafan, en esta generación, su memoria es compactada

    Si nuestra aplicación está perdiendo memoria como consecuencia de no soltar todas las referencias a objetos que ya no van a usarse, forzar la llamada al recolector no va a sino agudizar el problema: por un lado, no va a recuperar la memoria de objetos indebidamente alcanzables por lo que la falencia original persistirá; pero aparte va a acortar cambios generacionales innecesaria e improductivamente, con impacto -claro- en el rendmiento general. A esto se le ha dado el curioso nombre de "crisis de los 40" (midlife crisis) o como la canción de Jethro Tull, "demasiado viejo para el rock, demasiado joven para morir". El tema es que la llamada prematura hace que objetos que en cualquier otra circunstancia no hubieran salido de la generación 0, acá terminan en la 1 o la 2 ya que la alta frecuencia de intervención del recolector los soprende todavía "alcanzables" (por ende, por lo que contaba antes, pasan a la generación siguiente). Mover objetos entre generaciones es caro: esos ciclos de CPU los podrían aprovechar hilos efectivos de la aplicación. No debemos olvidar acá que no es sólo cuestión de copiar bytes entre segmentos sino también compactar a los mismos. Todo eso es CPU sólo para una tarea administrativa

    Llamar al recolector en forma explícita mediante GC.Collect() va a correr en el mismo hilo de ejecución en que se estaba ejecutando el método que contiene esta llamada. Por consiguiente, la instrucción siguiente al pedido de recolección no va a ser ejecutada hasta que la recolección finalice

     

     

    Y hay algo aún peor que la "crisis de los 40", en lo que a forzar recolección en escenarios de pérdida se trata: en la medida en que no haya mucho para recolectar, el recolector igual se tuvo que barrer todos los objetos para conocer cuántas referencias alcanzables por dominios de aplicación tenían

    El algoritmo no es trivial: no es cuestión de tener una tabla con referencias porque puede pasar que tengamos una serie de objetos que se referencian circularmente, pero que ese circuito no sea alcanzable; sin embargo cada elemento del grafo tiene al menos alguna referencia. Detectar tales circuitos es parte del cuento (y todo es, nuevamente, CPU)

     

     

    Veamos todo esto en la práctica. Acá tengo la siguiente aplicación: por un lado tenemos una clase que vamos a invocar desde el resto de la aplicación (llamemosla, por ende, Invocado). Invocado se define como sigue

        class Invocado
        {
    // contador de invocaciones a lo largo de la vida de la instancia
    int cantLlamadas = 0; public string[] Invocar() { string[] arregloARetornar = new string[1000]; // se actualiza el contador de invocaciones ++cantLlamadas; for (int i = 0; i < arregloARetornar.Length; i++) { arregloARetornar[i] = "Iteración "+ cantLlamadas+ "; Elemento "+ i; } return arregloARetornar; } }

    Basicamente, tiene un método, Invocado.Invocar(), que crea un arreglo básico de mil cadenas de caracteres y las inicializa a todas con un texto unívoco (conteniendo la invocación general al método y el número de string creado). Este arreglo con todos sus elementos, es devuelto al llamador

    Paremos la película acá: el arreglo creado, con todos sus elementos, es devuelto al llamador

    Lo que el llamador recibe, en verdad, es una referencia al arreglo. Si el llamador, luego de recibirla y procesarla, se deshace de esa referencia, tenemos la plena seguridad de que ese arreglo con todos sus elementos va a quedar disponible para que el recolector de basura lo levante (y, como conté anteriormente, eso va a pasar en la medida en que el recolector pase por la generación en que este objeto ya no referenciado se encuentre: si liberó memoria suficiente en generaciones anteriores, este objeto amigo va a sobrevivir)

     

    La clase que sigue es la que va a llamar a la que vimos recién. Por consiguiente la voy a llamar Invocador. La misma tiene un método, Invocador.Comenzar(), que va a gatillar la creación de una instancia de Invocado, cuyo método Invocado.Invocar() va a ser llamado cien veces

        class Invocador
        { 
            List<String[]> listaResultados = new List<string[]>();
    
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { #if RECOLECTANDO GC.Collect(); #endif resultados = invocado.Invocar(); // El arreglo de strings (con todas sus referencias), se enlista // (de modo que no serán elegibles para recolección) listaResultados.Add(resultados); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); } } } }

    Lo que es interesante de apreciar en este ejercicio es que Invocador habilita compilación condicional según que queramos forzar recolección de basura. El símbolo condicional es RECOLECTANDO

    Si te fijás en el código, más arriba, por un "presunto" error de diseño las llamadas a Invocado.Invocar() se van acumulando en listaResultados. Cada elemento de listaResultados es un vector de 1000 string por lo cual, mientras listaResultados sea accesible, sus 100 string[] son accesibles y, por cada uno de estos 100 string[], sus 1000 string son accesibles. En otras palabras, como listaResultados va a ser alcanzable durante casi toda la ejecución, sumemos las referencias a 100 string[] (vamos 101 referencias) y 100.000 (cien mil) string. Total: 100.101 (cien mil ciento un) referencias visibles simultáneamente para cuando la aplicación termine

     

    Pues bien, en lo que sigue vamos a comparar dos corridas: ambas perdiendo memoria pero una de ellas dejando que la recolección se dé espontaneamente en tanto que la otra la va a forzar en cada iteración. Para ello me valí de una facilidad de Windows que es el tradicional Monitor de Rendimiento (Performance Monitor). Si no estás familiarizado con el mismo, dejame contarte que es una herramienta súper útil para ver qué pasa con la salud de tu aplicación. Vale 0 (cero, o huevo como dirían en Chile). Es parte del sistema operativo y no sólo tiene varios grupos de parámetros a monitorear sino que además te permite monitorear equipos remotos! Como si fuera poco, vos mismo podés definir tus propios paquetes de parámetros monitoreables. Pero veamos ahora qué pasó con nuestra aplicación, comparando recolección por defecto versus recolección forzada:

     

    # Bytes in all Heaps # Bytes in all Heaps

    Tamaño del montículo de memoria administrada a lo largo de la ejecución (# Bytes in all Heaps)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    A la izquiera tenemos el perfil de ejecución que no fuerza la recolección. Curiosamente, y esto no es que pase siempre sino en este particular caso donde la aplicación pierde memoria, forzar la recolección no hace sino que la aplicación consuma más memoria. Re loco, no? Puede llegar a llevar a la errónea conclusión de que forzar la llamada al recolector hace que siempre una aplicación consuma más pero tampoco es que sea así: esta aplicación, lo sabemos, pierde memoria en la medida en que mantiene "vivas" referencias a objetos no utilizados. Ergo, llamar al recolector para que se haga cargo de una situación en la que poco puede intervenir es como llamar al pintor para que nos pinte una pared que se arruinó por la humedad, sin hacer ningún tratamiento a este último problema

    Llamar al recolector explícitamente no es gratis: si vos lo llamás, claro está, el tipo va a venir y su hilo va a competir por la CPU contra el resto de los hilos del proceso (y, a su vez, el proceso de esta aplicación respecto de sus pares). En el gráfico que viene vas a ver cómo esto se refleja

     

    % Time in GC % Time in GC

    Porcentaje de uso de CPU que se lleva el recolector de basura por sobre el total del CLR (% Time in GC)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    Si te fijás en el gráfico de la derecha, es decir forzando recolección, vas a ver que el share que el recolector se come en la pizza es incrementalmente mayor (el eje horizontal es el tiempo). La explicación de esa participación incremental es que el pobre recolector se tiene que recorrer un número incremental de elementos (aquellos que hacia el final van a totalizar 100.101) sólo para darse cuenta que no hay nada que hacer con ellos porque son alcanzables

    Si miramos, en cambio, qué pasa sin forzar recolección, la intervención del recolector se mantiene moderadamente baja, excepto un peek que se produce casi al final. Y esto se puede ver mejor si contamos, para cada generación, cuántas recolecciones efectivas se llegaron a hacer en las mismas

     

    # Gen x Collections # Gen x Collections

    Cantidad acumulativa de recolecciones en las tres generaciones (# Gen x Collections)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    En la ejecución normal tenemos en total 22 recolecciones de la generación 0, 4 recolecciones de la generación 1 y 2 recolecciones de la generación 2. Forzando recolección de memoria, tenemos 100 recolecciones en las generaciones 0, 1 y 2. Acá está la famosa crisis de los 40 de la que te hablé anteriormente (producto de andar jorobando con recolecciones que hacen que cualquier sobreviviente pase a la generación siguiente, con el consecuente overhead de cambio generacional). Para percibirlo en mejor detalle, te propongo que analicemos los tamaños de los segmentos a lo largo de la ejecución

     

    Gen 0 heap size Gen 0 heap size

    Tamaño del montículo de la Generación 0 (Gen 0 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    En el caso de la izquierda, sin forzar recolección, tenemos alrededor de 5,5 megas en la generación 0. Esto te da cierta pauta de cuánto llega a medir el montículo de esa generación (un poco más de 6M en este caso). Cuando el montículo creció algo más allá, se quedó sin espacio y el recolector enderezó las cosas mandando sobrevivientes a la generación 1 (y eso, como te contaba antes, pasó 22 veces)

    En cambio, forzando recolección, la generación 0 se mantuvo dentro del 1,5M lo cual -ahora que vimos que el montículo tenía espacio para seguir creciendo arriba de los 6M- nos da la pauta de que lo hemos estado saneando cuando apenas llevaba una cuarta parte de su capacidad ocupada

    Veamos, para entender esto mejor, cómo anduvieron las otras generaciones

     

    Gen 1 heap size Gen 1 heap size

    Tamaño del montículo de la Generación 1 (Gen 1 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)
     

    He aquí, señoras y señores, la crisis de los 40 reflejada: en la ejecución normal, el tamaño de ese montículo tuvo un gran ascenso hasta que devino su abrupta caída (creció hasta los 4,5M aproximadamente). En esa caída es donde el recolector mandó a la generación 2 a los sobrevivientes. En cambio, en el caso de la recolección forzada, se puede notar que la generación 1 siempre se mantuvo dentro de los 211,5K!! En otras palabras, los objetos entran e inmediatamente se van. Todo ese overhead, claro, se paga con CPU

     

    Gen 2 heap size Gen 2 heap size

    Tamaño del montículo de la Generación 2 (Gen 2 heap size)
    A la izquierda, sin forzar recolección. A la derecha, forzando recolección (hacé click en las imágenes para verlas mejor)

    Acá aparece la madre del borrego: la generación 2, en la ejecución normal, viene piola dentro del 1,37M en la medida en que la generación 0 va creciendo, hasta que los sobrantes van pasando a la 1. No te olvides que mientras no se fuerce recolección, el recolector barre una generación primero y, de no haber conseguido memoria suficiente, pasa entonces a la generación siguiente (y así sucesivamente). Por ello la generación 2 pega un gran salto ya en la segunda mitad de la ejecución, cuando es evidente el arrastre de memoria perdida que viene sobreviviendo de las agotadas generaciones anteriores

    En el caso forzado, este segmento viene creciendo lozanamente mientras los otros dos se mantienen por debajo de sus valores de ocupación plena. Al forzar la intervención del recolector de basura no hacemos más que mover bytes entre segmentos, para una ejecución que finalmente terminó consumiendo más. Qué tul?

     

    En fin. Hay otros contadores más de memoria que no utilicé en este caso. Para una descripción total de los mismos te recomiendo que visites el documento "Contadores de Rendimiento de Memoria" en MSDN

    Configurar el Monitor de Rendimiento es realmente fácil. En la figura de abajo te muestro un detalle al elegir para mi propia compu (<Local computer>, porque también podía haber elegido alguna de la red), algunos parámetros medibles de la categoría .NET CLR Memory, filtrando por la instancia del proyecto que tenía abierto en Visual Studio (MemoryLeakProducer.vshost)

    Configurando el Monitor de Rendimiento

    Agregando contadores en el Monitor de Rendimiendo para un proyecto Visual Studio 2008


    Entonces, ahora que eximimos de culpa a la máquina virtual por las pérdidas de memoria y logramos volver a echarnos la culpa -como siempre- a nosotros mismos, veamos a nivel arquitectónico cómo debería usarse y desecharse la memoria

     

    Ciclo de Vida de los Objetos

    En esta era nuestra de la arquitectura de soluciones (solutions architecture), del desacoplamiento (decoupling) y de la separación de intereses (separation of concerns o SoC), es muy posible que el proceso de creación de objetos (junto con la inicialización de sus propiedades, que a su vez puede implicar el crear otros objetos) sea delegado a métodos fabricantes. Estrategias hoy para encapsular esos detalles hay varias, pero por mencionar algunas: fábricas concreta y abstracta e inyección de dependencias (yo mismo escribí hace dos años atrás un artículo sobre Inversión de Control que comentaba cómo fue evolucionando el desacoplamiento en la instanciación y el uso de componentes)

    A simple vista, puede haber un impulso a considerar que la responsabilidad de desasignar objetos les cabe a quienes los crean (es decir, yendo a lo concreto, a las fábricas, inyectores de dependencias, etc). Pero a no equivocarse: como dice el refrán, la culpa no es del chancho sino de quien le da de comer. Si una determina clase C, en algún método M, manda a crear un objeto O a una fábrica F, empieza a verse como claro que es C es la que decide que el objeto sea creado (la fábrica F no lo fabricó espontaneamente sino respondiendo a C en su método M). Podríamos decir entonces que le va cabiendo más a C que a F, desprenderse del objeto

    A la vez, C pudo haber mandado a F a crear el objeto para ponerlo al alcance de un invocador I (aquel que llamó al método M de C). Si en definitiva el objeto se lo va a quedar I, ya no es tan claro que C deba encargarse de desasignarlo (y mucho menos a F!! smile_omg)

    En realidad, dado el siguiente escenario donde un invocador I llama a un método M de una clase C, en donde a su vez se va a pedir a una fábrica F que crée a un objeto O que va a ser retornado a C puede pasar que C haga con él lo siguiente:

    1. Lo guarda en una propiedad P de sí mismo (de C). En ese caso, que sea C quién decida más tarde sobre su destino
    2. Lo devuelve a un invocador I. Vayámonos olvidando de C y F respecto de ese objeto O. La cosa pasa por I o a su vez por quienes dieron intervención a I
    3. Lo asigna a una propiedad P de un argumento A recibido en la llamada a M. Similar al caso anterior: pasa ahora a ser A responsable de deshacerse en algún momento de la referencia (eventualmente cuando la misma A quede desreferenciada)
    4. Lo mantiene en una variable V local al método M. El objeto O va a ser recolectable cuando V pierda visibilidad (a más tardar, al finalizar M)
    5. Lo pasa como argumento a un método M' de una clase C'. En tal caso, de guardar C' una referencia a O, deberá encargarse luego de perderla

    Como se puede ver, el problema del ciclo de vida de los objetos es bastante más complejo que la simplicidad de decir "que el que rompa, después arregle" smile_teeth. A cambio te propongo un enfoque de más alto nivel (por así decir, arquitectónico) para lidiar con este problema. La propuesta es segmentar las instancias de clases según su alcance. A saber:

    • Nivel de Aplicación. Aquellas instancias que, aunque no necesariamente se créen al levantar el proceso de la aplicación (te estoy hablando a nivel de sistema operativo), una vez que surgen, son necesarias hasta que la aplicación sea desmontada
    • Nivel de Sesión. Similar pero usando como timeframe (marco de tiempo) desde que un usuario se logonea hasta que el mismo sale (o su sesión expira). En los tiempos actuales de Arquitecturas Orientadas a Servicio (Service-Oriented Architecture o SOA), el sujeto de la sesión puede ser un usuario o bien un proceso remoto. Normalmente las instancias a nivel de sesión tienen un condicionante (constraint) de privacidad entre sesiones, de modo que sólo puedan ser accedidas por la sesión a la que pertenecen. Esto refuerza la idea de disponer de dichas instancias una vez que la sesión caduca
    • Nivel de Caso de Uso. Dentro de una sesión, a su vez, el usuario o proceso puede iniciar más de un proceso de negocio (comprar pasajes, contratar servicios, ver un resumen de movimientos, etc). Actualmente por cuestiones de experiencia de usuario (user experience o UX) es muy factible que las pantallas que componen el caso de uso se compongan de pasos (en modalidad wizard o asistente) donde el usuario va cargando parte de los datos, y los restantes -en pasos posteriores- van a ser dependientes de los primeros. Es frecuente en estos casos que instanciemos objetos sólo dentro de la vida del caso de uso: sea que el usuario finalice exitosamente o cancelando, los mismos ya no serán menester
    • Nivel de interacción (o actividad, en el caso de workflows). Todavía hilando algo más fino el nivel anterior, especialmente en aplicaciones web o al ejecutar actividades de workflows, existen objetos que se instancian sólo para ejecutar esa particular circunstancia. La vida de estos objetos suele ser muy corta y dependiendo de la carga de trabajo de los servidores que los ejecutan, a veces se suelen reusar para evitar el overhead de crear, liberar instancias mediante la inclusión de un pool de objetos. No obstante, apelar a este tipo de soluciones debería hacerse sólo luego de determinar que el CLR lleva demasiado tiempo creando y liberando objetos

    Un caso extra, no comentado, son los workflows de ejecución prolongada (procesos cuyo lapso total de ejecución podría medirse en horas o días). Normalmente el estado de estos flujos que quedan pendientes de continuación son persistidos para poder ser retomados más tarde. Esa persistencia incluye instancias que van a ser requeridas al retomar (veamos al workflow algo similar al nivel de caso de uso). En la medida en que son persistidas, por ende, pueden ser liberadas

    En la medida en que entandamos estos niveles, podemos organizar nuestras instancias para procurar que sean desasignadas según que el nivel al que pertenezcan caduque. A quién le cabe desasignar instancias? En cada nivel hay un objeto que lleva el control del mismo. Por ejemplo, en el nivel de sesión será un objeto que cumpla el rol de "administrador de sesiones" (que es quien acusa recibo de un usuario que se desloguea o que una sesión expiró). A ese objeto no le cabe directamente la desasignación de todos los objetos de ese nivel, pero sí el gatillarla

    Algo muy piola, para cualquier nivel pero lo ejemplifico con el nivel de caso de uso, es que si todos los objetos de este nivel son alcanzables pura y exclusivamente desde un objeto general (creado para la ejecución del caso de uso), al deshacernos de este objeto general (dejar de referenciarlo) ya no habrá más forma de alcanzar al resto de las instancias del nivel. Si te fijás, a nivel de sesión, esta estrategia es la que usa ASP.NET con su objeto Session. Bueno, así es justamente como ASP.NET procura que no le queden instancias colgadas dentro del rango de una sesión si la sesión en que se crearon expiró

     

    En una segunda derivada de este análisis, el control de instancias mediante la alineación a de las mismas al nivel correspondiente según su ciclo de vida como objeto se complementa con el control referencial. Tanto en Java como en .NET, una variable o propiedad de una clase declaradas de determinado tipo T no primitivo (es decir, no entero, flotante, booleano, etc) no guardan el contenido de ese tipo, sino una referencia (sí, exacto: un puntero a memoria) a otro objeto del tipo en cuestión

    En nuestro ejemplo de arriba, la clase Invocador tiene un miembro llamado listaResultados de tipo List<string>. Pues bien, listaResultados no contiene tal lista sino que listaResultados es un puntero a otro objeto en memoria que sí contendra esa data. Las ventajas del código administrado (managed code) es que nosotros ni debemos concientizarnos de que son todos punteros: el entorno de ejecución administrado se encarga de todo eso

    La realidad es que si declarásemos una variable v del mismo tipo que listaResultados y le asignásemos listaResultados, lo que se asigna es el puntero. Como consecuencia, no van a quedar dos copias en memoria sino que cualquier alteración al objeto de tipo List<string> refenciado por listaResultados, va a ser percibible accediento al objeto desde v (y viceversa). En otras palabras, listaResultados y v hacen referencia al mismo objeto

    Si en un momento dado listaResultados desaparece (por ejemplo, porque su objeto contenedor Invocador fue levantado por el recolector de basura, el objeto de tipo  List<string> apuntado por listaResultados aún no es pasible de ser recolectado porque... al menos la variable v (si no otros punteros también) todavía lo están referenciando  

    Control de referencias o control referencial, entonces, complementa al control de instancias en la medida que asegura que si un objeto O pertenece a determinado nivel N, cualquier referencia al objeto (sea una propiedad en una clase, sea una variable de programa, sea un argumento de un método aún en ejecución, o cualquier otro puntero) no va a durar más allá de ese nivel. De hacerlo, de trascender al nivel al que pertenece, el objeto O también va a trascender ese nivel y el recolector de basura no va a poder llevárselo en la medida en que aún esté siendo referenciado por otras variables u objetos alcanzables

     

     

     

    Volviendo al caso de la aplicación que pierde memoria, veamos estos conceptos de control de instancias y control referencial en la práctica

    Nuestra aplicación estaba innecesariamente, al enlistar resultados en listaResultados, otogando a los mismos "nivel de aplicación" ya que listaResultados es un miembro de la clase Invocador que se crea al iniciarse la ejecución y se desasigna al finalizar. Por ende, primera medida en este ejemplo, chau listaResultados

        class Invocador
        { 
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { resultados = invocado.Invocar(); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); } } } }

    Optimización I - Aplicando Control de Instancias, la serie de resultados deja de tener nivel de aplicación

     

    Ahora vamos a repasar resultados de la ejecución con esta primera optimización pero aún antes de seguir tenemos otra disponible: si te fijás, en el último loop (aquel que despliega por consola los resultados), una vez que ejecutamos una iteración j, el elemento de dicha iteración (resultados[j]) ya no va a ser accedido en el resto de este ejemplo. Aplicando control referencial, entonces, qué pasa si lo desasignamos "in situ"? Tan sólo se necesita asignarle null a dicha entrada para que deje de referencias al string como lo venía haciendo. Con esto, aunque éste es un ejemplo trivial, le estamos dando a cada entrada de resultados un nivel similar al de interacción (en el sentido de una vida resumida a la máxima brevedad posible)

    Entonces, con esta nueva optimización, nos queda

        class Invocador
        { 
            public void Comenzar()
            { 
                Invocado invocado = new Invocado();
    string[] resultados; for (int i = 0; i < 100; i++) { resultados = invocado.Invocar(); // Recorremos el arreglo resultante haciendo "algo" con sus // elementos (en este caso, mostrarlos por consola) for (int j = 0; j < resultados.Length; j++) { Console.WriteLine(resultados[j]); resultados[j] = null;
    } } } }

    Optimización II - Como consecuencia de un Control Referencial, cada entrada en resultados es desasignada cuando ya no se va a usar

     

    Vamos a comparar las dos ejecuciones:

     

    # Bytes in all Heaps # Bytes in all Heaps

    Tamaño del montículo de memoria administrada a lo largo de la ejecución (# Bytes in all Heaps)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    En primer lugar, tuve que cambiar el factor de escala para poder mostrar los gráficos. Si en las corridas del principio, perdiendo memoria, estaba hablando de un promedio de memoria reservada alrededor de los 2M (y un máximo en torno a los 9M), acá hablamos de un promedio inferior a los 200K (y un máximo debajo del mega)

     

    % Time in GC % Time in GC

    Porcentaje de uso de CPU que se lleva el recolector de basura por sobre el total del CLR (% Time in GC)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Un segundo beneficio que nos llevamos, al evitar pérdida de memoria mediante la correcta alineación de instancias de objetos a un nivel acorde a su ciclo de vida es que el recolector de basura no sólo va a hacer mejor su tarea de liberar memoria: la va a hacer más rápido!! La razón? Al encontrar instancias que sí deben liberarse, nuestro amigo va a evitar volver a toparse con ellas una y otra vez en sus futuras intervenciones. Nada de pasar a generación 1 o 2: arrivederci (como debe ser)

    Vale la pena destacar que en el caso II (a la derecha), con la máxima optimización, el recolector intervino la mitad del tiempo que aplicando sólo la optimización I (izquierda)

     

    # Gen x Collections # Gen x Collections

    Cantidad acumulativa de recolecciones en las tres generaciones (# Gen x Collections)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Lo primero que quiero hacerte notar es que en ambos casos no llegó a haber recolección en la generación 2. En otras palabras, incluso la optimización I alcanzó para que las intervenciones del recolector sean efectivas en las generaciones bajas. Las recolecciones de la optimización I solamente se repartieron así: 21 en la generación 0 y 6 en la 1. Aplicando además la optimización II, en cambio, hubo 27 recolecciones en la generación 0 y 3 en la 1 (más allá de que el número de recolecciones es mayor, la duración de las mismas fue eficientemente bajo -como te contaba antes, la mitad que lo que demoró el caso que sólo aplicó optimización I-)

     

    Gen x heap size Gen x heap size

    Tamaño de los montículos de la tres geeneraciones (Gen x heap size)
    A la izquierda, sólo aplicando Control de Instancias. A la derecha, Control de Instancias y además Referencial (hacé click en las imágenes para verlas mejor)

    Decidí optimizar aquí en un sólo gráfico las tres generaciones. A la izquierda (aplicando sólo optimización I) vemos que la generación 0 se mantiene alrededor de los 2,5M (con tres evidentes peek donde supera los 4M). Esto es menos de la mitad del tamaño que alcanzó en el esquema con pérdida de memoria. Pero la cosa es todavía mejor aplicando además la optimización II (a la derecha): entonces la generación 0 se mantuvo alrededor del mega. Con pequeños saltos hasta 1,5M. Sweet! heart

    La generación 1 se mantuvo oscilando alrededor de los 240K para la optimización I y, menos aún, 135K si añadimos aparte la optimización II (en las gráficas, es una muy chata línea celeste que se ve casi al 0 del diagrama)

    La generación 2, en ambos casos, se amesetó en los 118K y ya no bajó de allí por el hecho de que nunca llegó a haber recolección en la misma (en los diagramas es imperceptible). Pensá que en el ejemplo inicial, con pérdida de memoria, estuvo un buen rato dentro del 1,37M hasta que se disparaba a los 6M y más

     

    Por sobre todo, creo haber dejado con estas dos optimizaciones, más que claro que enfrentar el problema de "la gotera" de memoria es definitivamente más efectivo que forzar la supérflua intervención del recolector de basura. Pasemos ahora a ver cómo se enfrenta el problema de "la gotera"

     

    Detectando Leaks: el CLRProfiler

    El ejemplo que hemos usado en esta aplicación es trivial y muy ad hoc para mostrar rápidamente cómo tocando algo cambia copernicanamente la situación. Pero en las aplicaciones que a vos y a mí nos tocan mantener, la cantidad de clases son infernales, y aún muchás más sus instancias de objetos por lo que más allá de los indicios que a priori puedas tener... la verdad es que podés estar días buscando la causa. Si tu aplicación está en producción hablar de "días" en lugar de "horas" para resolver un problema es un lujo que no te vas a poder dar

    Para esto existe una herramienta que te permite perfilar el comportamiento del CLR durante la ejecución (memoria consumida, tiempo de vida según tipos de datos, etc). Me refiero al CLRProfiler. Esta facilidad, como el Monitor de Rendimiento, también está disponible en forma gratuita aunque en este caso no viene incluído como parte del sistema operativo sino que se descarga de la web de Microsoft (la URL es http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&DisplayLang=en)

    Para el ejemplo de esta aplicación, perfilé la ejecución de la versión inicial, con pérdida de memoria, recibiendo estos resultados:

     

    Histograma por edad

    Un histograma según la "edad" de los objetos me muestra que un considerable número de megas ocupados durante lapsos que superan los 20, 30 y más segundos pertenece a objetos de la clase string (en rojo en el histograma)

    Que más del 90% de los objetos creados correspondan a string ya nos puede dar indicios de por donde empezar el control de instancias. Que, aparte, varios de estos tengan una vida tan prolongada, nos da la pauta de que podríamos tener que aplicar optimización referencial

    Entonces nos preguntamos, y estos string dónde es que se originan? Revisemos el grafo de asignación de memoria que nos tira CLRProfiler:

     

    Grafo de alocación

    Y acá siguen apareciendo elefantes: el método Invocado.Invocar() se lleva un 75.27%, esto es, las tres cuartas partes de la allocación total de memoria. Como vimos antes, eso no quiere decir que él deba allocar menos sino que es acá donde se origina el grueso. Pero luego nos resta ver a nosotros dónde se debería desasignar esa memoria. Por ahora, completemos lo que vinimos a buscar: en este caso, que indirectamente, Invocado.Invocar() termina generando la creación de string por un total equivalente al 42% de la memoria total. Estos string que, como veíamos, duraban en algunos casos arriba de los 30, 40 segundos

     

    Entonces, con estos elementos, sí nos mandamos a la aplicación a revisar quiénes están llamando a Invocado.Invocar() y qué hacen con lo que este método devuelve. Para dejar constancia, luego de aplicar las dos optimizaciones que te mostré antes, basándome en la regla de los niveles según ciclo de vida, volví a perfilar la aplicación y el histograma me mostró lo siguiente

     

    Histograma por edad

    La mayoría de los string ahora muere en menos de 10 segundos (antes era todo lo contrario). Se ve?

    Moraleja de este post: si una aplicación consume mucha memoria, no es cuestión de forzarla a que instancie menos objetos que los necesarios sino de asegurarse que estos sean recolectados cuando ya no se necesiten

     

     

    Algo así como acordarse de sacar siempre la basura a las 8 de la noche Wink (o de la tarde, si estais en España, jo'er!). Estamos aplicando acá Pensamiento Lateral (Lateral Thinking) 

     

    Bueno, me voy despidiendo acá pero te dejo algunas referencias interesantes para seguir explorando:

    January 05

    Llegan los Reyes: Sesiones Completas del Foro de Arquitectura de Microsoft Corp

    clip_image002

     El  pasado Noviembre se realizó el Foro Anual de Arquitectura en el Centro de Convenciones de Microsoft. Este tipo de eventos es bastante diferente, si lo comparamos, al track de Arquitectura que se incluye en la conferencia TechEd de desarrollo de software. Es sabido que, en nuestra industria, el término "arquitecto" es tomado con mucha amplitud y dependiendo del contexto hace referencia a roles de diferente seniority. Podríamos decir que el estilo de arquitecto que asiste a este foro es más bien aquel que está más allá de una aplicación específica, pero que está en todas al mismo tiempo en la medida en que entiende cómo éstas se organizan para soportar el famoso "negocio" que su organización lleva adelante

    Por tal motivo, las sesiones de este foro hacen mucho hincapié en lo que viene en cuanto al aprovechamiento que toda organización pueda hacer de ellos en términos de su relación con clientes, proveedores, socios comerciales y, finalmente, sus propios procesos internos de TI (control de cambios, ciclo de vida, etc). En ese sentido, no esperes acá ver grándes demos de cómo se configura tal cosa para habilitar REST en lugar de SOAP, etc sino más bien por qué REST y no SOAP o viceversa

    Para marcar otra diferencia con TechEd, esta conferencia no es de entrada libre al público sino que es por invitación de Microsoft a sus clientes. Por tal razón, los asistentes son sólo un selecto grupo. Como contrapartida, lo bueno es que lo que se muestra acá -como vas a ver ahora- luego es publicado en forma completa. En el caso de TechEd, sólo si la organización del TechEd así lo dispone (y, al menos la última vez, se dispuso que no smile_sad)

    El pueblo quiere saber de qué se trata

    Día 1

    Ver Sesión

    PPT

    Cambiar el Mundo con Software y Servicios
    Donald Ferguson comienza listando las tendencias actuales derivadas de los últimos adelantos en tecnología que, innegablemente, cambian cada vez más nuestra vida y la forma de consumir cosas u obtener información. Entonces plantea el típico escenario de una compañía hipotética que agrega valor a sus procesos mediante el consumo de servicios provistos por terceras partes, analizando el impacto tanto para dicha compañía como para el proveedor de ese servicio e incluso ya para aquellos terceros que quieran -a su vez-, agregar valor a sus procesos consumiendo ya no los servicios del tercero original sino los de la compañía tomada como centro de la hipótesis
    En concreto, SOA ya no está sólo en este mundo de servicios: los mashups y las RIAs (aplicaciones basadas en Internet que aprovechan a full recursos del dispositivo en que se ejecutan) son hoy parte del ecosistema

    video

    presentacion

    Anatomía de una Aplicación Software + Services
    Eugenio Pace (ex Patterns and Practices donde dirigió el Composite Application Block y la derivada Smart Client Software Factory que hoy sigue llevando adelante Glenn Block) baja algo más a la tierra las ideas del keynote de Ferguson, explicando con admirable precisión el ecosistema S+S donde unos consumen servicios, otros los desarrollan y unos terceros los ejecutan (percibiendo así su parte de la pizza). Eugenio luego presenta un pantallazo de lo que Microsoft está ofreciendo hoy en su estrategia S+S, con servicios fundacionales (por ejemplo para identificación o para video streaming), otros agregables por suscripción (como OneCare o XBOX Live) y servicios de rango superior (ejemplos tales como Office Live, Windows Live o Dynamics CRM)

    video

    presentacion

    REST: un Enfoque Liviano, Orientado a Datos para el Software Concurrente y Distribuido en Empresas
    George Chrysanthakopoulos, investigador en Microsoft Research, nos muestra un pantallazo de Microsoft Robotics Studio: un kit de aplicación de conceptos como orientación a servicios pero para aplicaciones que incorporen robótica (una introducción decente a Microsoft Robotics Studio está disponible acá). A lo largo de su charla, el presentador nos va a mostrar -en los papeles y en la práctica- el modelo descentralizado de aplicación para servicios de software (DSS) y el motor de ejecución para concurrencia y coordinación, que permite orquestar señales asíncronas con simplicidad como horizonte. El modelo de programación no es C++ ni nada sólo para una elite: toda la plataforma Robotics es .NET

    video

    presentacion

    Levantando las Barreras para la Voz por IP (VoIP)
    Gurdeep Pall (ex miembro del equipo de Arquitectura que integro y actual vicepresidente corporativo de Microsoft para el grupo de Comunicaciones Unificadas) ofrece una sesión muy interesante sobre un aspecto que hoy las organizaciones vislumbran como uno de los peores enemigos de la productividad: la sobrecarga derivada de las facilidades que hoy las comunicaciones ofrecen (dicho en otras palabras, el tiempo que hoy los empleados independientemente del rango dedican a ver y responder correos, asistir a reuniones y otros esquemas de comunicación). Gurdeep se propone mostrar una plataforma novedosa, MS Unified Communications, que surge como una forma de responder a las siguientes preguntas: cómo priorizar comunicaciones para poder reaccionar en una forma más productiva? cómo aprovechar la infraestructura existente en conjunto con Internet para abaratar los costos de las comunicaciones? cómo integrar toda la plataforma (telefonía fija, celular, la red de computadoras, etc?). Como cierre, vas a poder conocer la interfaz de voz del Outlook (si no la conociste ya)

    video

    presentacion

    Proyecto Astoria: Servicios de Datos para la Web
    Pablo Castro, del equipo ADO.NET nos da un pantallazo de hacia dónde esta API de acceso a datos va a extender sus dominios (estimativamente, hacia mediados de año). Astoria es un framework para poder consumir información tanto dentro de la empresa como hacia afuera, basándola en los protocolos REST de la Web 2.0 (ATOM, JSON). La idea de esto es que las organizaciones puedan poner su información disponible para clientes HTML, Silverlight, mashups o clientes de escritorio que sean capaces de consumir datos en estos formatos

    video

    presentacion

    Arquitectura de Aplicaciones Compuesta Usando 2007 Office System
    Con probablemente una de las sesiones que más te voy a recomendar, Scott Jamison repitió acá el éxito que logró en el track de Arquitectura del pasado TechEd, cuando alcanzó el mejor score como orador en una sesión similar. Normalmente venía produciendo cierto rechazo la sola mención de Office 2007 o específicamente Sharepoint 2007 en una charla de arquitectura (en parte aventados por los dolores de cabeza ocasionados por las versiones anteriores de este último), en tanto que era recibido como un "sales pitch" (una venta, basicamente hablando) de un producto Microsoft. Hoy podemos decir ya que cierta agua ha corrido bajo el puente, y algunos resultados tangibles se empiezan a notar. En esta sesión vas a ver ejemplos concretos -y de arquitectura- en los cuales los beneficios de aplicar Sharepoint como columna vertebral de una aplicación que se compone de cachitos de aplicaciones existentes saltan a la vista. La calidad técnica de esta sesión es especialmente notable

    video

    presentacion

    Día 2

    Ver Sesión

    PPT

    Amazon.com: Simple Storage Service (S3), Elastic Compute Cloud (EC2) y Simple Queue Service (SQS)
    Charlie Bell, vicepresidente de Tecnología en Amazon Web Services, nos sorprende contándonos cómo las necesidades de evolución de la aplicación de Amazón dieron lugar a una serie de servicios que, si bien originalmente se habían concebido para poder mantener el portal en funcionamiento, son hoy una fuente de ingresos para esa compañía ya que los vende a terceros. Una historia impresionantemente Web 2.0 que bien podría mañana tenerte a vos como protagonista

    video

    presentacion

    Viaje al Centro de Microsoft Research
    Behrooz Chitsaz nos ofrece un panorama de la usina de investigación de Microsoft, cómo ha ido creciendo e instalándose en países tan diversos como China, Israel o la India, cómo colabora con universidades (a la vez que se nutre de ellas) y -por sobre todo- unas interesantes demos de reconocimiento de lenguaje natural, análisis de redes de datos, reconocimiento facial, biología computacional y más. Vale la pena tener en cuenta que de este laboratorio han salido la TabletPC (con su reconocimiento de letra escrita), el buscador de escritorio, el chequeo de sintaxis del Office o la próxima mesa programable Microsoft Surface, entre varios otros logros

    video

    presentacion

    Una Capa de Identificación Basada en Reclamos para la "Nueva Internet"
    Es sabido que el manejo de identificaciones en Internet ha ido evolucionando por mecanismos dispares al compás en que los usos de Internet también evolucionaban. Hoy usamos la internet como mecanismo de transporte no sólo para que personas consuman servicios sino para que procesos hagan lo mismo. A esta altura poder manejar un modelo unificado de identificación parece quimérico. Y sin embargo es lograble, como lo va a demostrar Slava Kavsan en esta sesión

    video

    presentacion

    Duet: Software Más Servicios de la Mano de Microsoft y SAP
    Para quienes no lo conocen, Duet es una forma de enlazar aplicaciones SAP con una fachada más familiar e integrada a través de las aplicaciones Office tradicionales. Lo que me pareció más valuable de esta sesión -si bien yo no me dedico a temas de CRM- fue la interesante discusión de problemas de arquitectura que han ido surgiendo a lo largo de la evolución de esto que originalmente apareció como "Proyecto Mendocino", y cómo se han ido resolviendo. La sesión fue ofrecida por Chris Keyser y Burra Gopal por parte de Microsoft, y Adi Kavaler por parte de SAP

    video

    presentacion

    El Futuro del Datacenter (I)
    Debra Chrapaty nos cuenta cómo Microsoft está planificando sus datacenters para hacer frente al escenario consolidado de software más servicios. Enterate de las distintas estrategias que están evolucionando para ofrecer alta disponibilidad y confiabilidad de lo que las aplicaciones esperan encontrar "allá en la nube"

    video

    presentacion

    El Futuro del Datacenter (II)
    John Dwyer ofrece otra perspectiva respecto de como los datacenters están evolucionando. Esta vez el enfoque tiene que ver con la creciente consolidación de los mismos y la demanda energética que se avizora, en conjunto con regulaciones necesarias para mantener nuestro medio ambiente verde (o mejor dicho, volverlo a ver verde algún día y no negro azabache como va camino a). Esta sesión es del paladar de los arquitectos de Infraestructura

    video

    presentacion

    Experiencia de Usuario en la Plataforma Windows Live
    La historia que David Dumler y Angus Logan nos cuentan acá es en cierto modo similar a la de Amazon que te mostré más arriba, sólo que esta historia aún está evolucionando. Enterate cómo Windows Live ha ido madurando una serie de servicios de diferente granularidad, con la idea de poder lograr en el futuro próximo una plataforma disponible por todos para montar aplicaciones que maximicen experiencias de usuario inmersivas y personalizadas, disponibles en toda "la red", y aprovechables tanto por personas como por organizaciones que quieran ganar nuevos clientes y hacer crecer su facturación

    video

    presentacion

    Experiencia de Usuario para Arquitectos
    Simon Guest propone acá dejar por un rato de lado el debate de los datacenters, la orientación a servicios y los workflows para concentrarnos aunque sea por un rato en las necesidades del usuario final. Para ello nos va a presentar un esquema de trabajo en el cual los arquitectos de software se pueden basar para pensar la capa de interacción centrada en la idea de que quienes vayan luego a usarla no deban, por ello, sufrirla

    video

    presentacion

    Microsoft IT: Viaje al Centro de la Cocina de Microsoft
    Si Microsoft dice proveer herramientas de TI que permiten a los negocios evolucionar y crecer... Cómo la lleva Microsoft con todo eso? Será como la vende o será más bien un enfoque "casa de herrero, cuchillo de palo"? Neil Leslie y Barry Briggs responden la pregunta y te cuentan mucho más acerca de cuánto de lo que Microsoft vende, surgió inicialmente como iniciativa interna. Seguramente que el componente "suerte" existió en la historia de Microsoft (como también lo habrá habido en el caso Amazon y en cambio faltó en la recientemente desaparecida Netscape), pero esta sesión -como aquella de Amazon- se encarga de mostrar que no todo es casualidad

    video

    presentacion

    Día 3

    Ver Sesión

    PPT

    MySpace: Lecciones Aprendidas al Filo de la Web
    Cuando Aber Whitcomb fundó MySpace junto con otros amigos, pensaron que un modelo de trabajo reactivo (on demmand) era suficiente: si algo se rompía, se arreglaba y punto. Al principio ese modelo funcionó pero inmediatamente Aber y los suyos empezaron a notar cómo estaban dejando pasar oportunidades. Mirá está sesión y conocé cómo cambiando a un esquema proactivo primero y estratégico después, MySpace es hoy uno de los sitios de la llamada "web social" de mayor tráfico, ofreciendo una serie de servicios distribuidos altamente disponibles. La paradoja de lo importante que es saber cambiar a tiempo si se quiere seguir igual

    video

    presentacion

    Manual para Conducir a los que Desarrollan Software
    Paul Glen es un consultor que hace un tiempo atrás sacó un libro acerca de cómo liderar equipos de desarrollo de software. Esta presentación es interesante en la medida en que este tipo de equipos de trabajo suele tener particularidades propias que no están presentes en otros tipos de industria. Es una realidad que los desarrolladores suelen ser más leales a la tecnología que les gusta que a vos que sos su jefe y tratás de hacerles entender que "en este proyecto no la podemos usar". Glen habla de este y otros temas que suelen impactar en los aspectos emocionales de quienes desarrollan software, y a la larga determinan el éxito o fracaso de los proyectos

    video

    presentacion

     

    Hacía rato que veníamos necesitando una sorpresa así. Después de tantos años de mishiadura yo ya había dejado de poner los zapatitos porque pasaban los reyes y me los afanaban

    December 05

    Para Poner en el Arbolito: el Architecture Journal Reader (Beta)

    Platform Architecture Team

     Arrimándose  las fiestas y otro año que pasa volando, los del Equipo de Arquitectura de Plataforma Microsoft te queremos acercar la beta de una aplicación que esperamos te resulte piola

    El Architecture Journal Reader es una facilidad que te va a permitir recibir en línea la revista homónima (The Architecture Journal), que por si no la conocías, es una publicación trimestral que dirije Simon Guest. The Architecture Journal es traducido a varios idiomas, aunque ésa no es una actividad que hacemos nosotros sino que determinadas subsidiarias de Microsoft, según el presupuesto, etc, traducen ciertos números a idiomas locales. La edición en español está disponible a partir del número 3 (desconozco la razón por la cual nunca se tradujeron los números 1 y 2 porque -como contaba- no pasa por mí traducirlo)

    El contenido de la revista, contrariamente a lo que puedas pensar, no es exclusivamente centrado en tecnologías Microsoft sino en tendencias de la industria (aplicaciones compuestas, SOA, Web 2.0, etc). De hecho la mayoría de los artículos de cada edición son contribuciones externas de arquitectos. Sí, quise decir eso: vos mismo podrías ser un contribuyente del Journal y sumarte un poroto ante tus pares. El call for papers se publica en un RSS feed suscribible acá: http://msdn.microsoft.com/architecture/arcJournal/rssCallForPapers.xml

    Para contenido específicamente Microsoft te recomiendo que visites el portal de Arquitectura MSDN

    El Architecture Journal Reader se instala localmente en tu PC y cada vez que lo abrís se sincroniza con nuestros servidores para descargar -dado el caso- las novedades disponibles. Y con esto no nos referimos exclusivamente a artículos: el Reader tiene un módulo de avisos publicitarios embebido entre las notas, de manera de poder comunicarte el próximo call for papers y/u otras novedades

     

    annotations-emphasizing 
    Figura 1 - Resaltado de texto y comentarios del lector

    Es una alternativa a leerlo directamente de la web, ya que los navegadores requieren de un acceso al servidor cada vez que quieras leer un artículo, y si por alguna razón no hay conexión disponible te van a tirar un error (no: el caché del browser con suerte va a funcar si le diste al back button para volver a una página cacheada en esa sesión)

    En este caso, en cambio, el proceso de descarga es una sincronización de datos que queda almacenada localmente (disparada ya sea bajo demanda o al abrir la aplicación). A partir de allí toda la navegación es local con lo cual no hay más ancho de banda involucrado hasta la próxima sincronización. Cada sincronización descarga sólo las novedades (esto es, artículos inexistentes localmente, o bien existentes pero con una versión local anterior). Si la sincronización no fuese posible por algún motivo (no hay conexión, etc), los datos preexistentes localmente siguen estando disponibles

    Pero la capacidad de operación fuera de línea (offline) no es la única ventaja ofrecida por este Reader: su idea es adaptar la lectura a las capacidades de despliegue en pantalla, entonces el texto y los gráficos se acomodan automáticamente al espacio disponible (te pasó en un browser de tener que escrolear para encontrar la imagen a que se hacía referencia, o agrandar el tamaño de la letra y que se desacomode todo?)

    Por ejemplo, fijate que la figura 1 que pegue más arriba. Quedó ahí: más arriba. Y aparece allí porque el tag HTML <IMG SRC="..."/> que puse, lo puse allí. Ahí queda pues. En cambio en esta aplicación, el texto se organiza según páginas de visualización en base al estado actual (tamaño del área de despliegue, etc). Si el vínculo a la imagen aparece en esa página de visualización, tenés garantizado que la imagen en algún lugar de la ventana se va a acomodar para que la puedas ver completa

    También, el texto se organiza automaticamente en columnas según el tamaño de letra elegido (más columnas si la letra es más chica, para que no te caigas del renglón smile_nerd). En ese sentido, las imágenes se escalan acorde a la cantidad de columnas disponibles

    El Reader te habilita a resaltar párrafos a los que luego quieras volver a ubicar, así como también agregar tus propios comentarios al texto. A ese respecto, te podés armar una lista de lectura (reading list) con artículos que quieras ubicar rápido (sin tener que acordarte en qué número habían salido publicados), similar a los bookmarks del browser pero, nuevamente, sin la necesidad tener que acceder al servidor cada vez

     

    reading_list
    Figura 2 - Lista de lectura consolidando artículos en varios idiomas

     

    Siendo que el Journal se viene publicando desde el 2004, a esta altura va juntando un buen volumen de data como para poder ubicarla inmediatamente. En general cada número tiene un tópico principal (SOA, Software as a Service, etc) pero siempre uno o dos artículos extra a ese tópico son también publicados. Por esto mismo, la aplicación incluye un buscador que clasifica sus resultados por orden de relevancia

     

    searching
    Figura 3 - Resultados de búsqueda de artículos relacionados con "modelo de datos", clasificados
    según relevancia de ese tópico en el artículo en general

     

    Con esta aplicación queríamos ejemplificar un par de cosas:

    • Software + Services. No es un mero cliché sino algo en lo que creémos de verdad. Yo mismo admito haber sido alguien que en su hora defendió a muerte el concepto de "ir a la web", "llevar todo a la web", y me cerraba el concepto de la "network computer" (una computadora de muy bajo costo que basicamente iba a ser capaz de conectarse a Internet y consumir la mayor parte de su software directamente de allí). Nunca pasó nada con la famosa "network computer" que alguna vez Larry Elison (CEO de Oracle) dijo que iba a marcar el fin de la PC y (no lo dijo pero todos esperaban que dijera) presuntamente del principal vendedor de software para PCs. Es hoy incluso difícil encontrar referencias a "network computer". Las más actuales que encontré son viejísimas: Microsoft (2001), Search400 (1999)
      Nunca pasó nada porque las PCs tradicionales con los años se fueron abaratando con lo cual la principal premisa de "ir a menos para ser más" perdió gravidez. Irónicamente esas compus baratas iban a costar entre 500 y 1000 dólares. Hoy eso es lo que cuesta una notebook con Windows Vista (sistema operativo éste que no cabe precisamente en un diskette)
      Software plus Services propone hostear atrás de la nube aquellos servicios que se actualizan dinámicamente, habilitando localmente una capa de software para aquellas funciones relacionadas con actividades del usuario junto a todo aquello que se quiera disponer en forma autónoma (aprovechando, de paso, recursos de hardware locales). Originalmente este concepto surgió como "smart client" (cliente inteligente), en contraposición al "thin client" (cliente delgado) que promovía "llevar todo a la web". Esa misma idea hoy se rebautizó como Software más Servicios (S+S) como una propuesta ampliada al Software as a Service (Software como un Servicio o SaaS). No como una alternativa a SaaS sino tomando a éste como un caso particular donde nada se hostea localmente
      En ese contexto podemos decir que la web del Journal actúa como SaaS en tanto que el Reader juega el rol de S+S, capisce?
    • User Experience (UX). Esto, aunque no parezca, es un derivado de aplicar S+S o, en otras palabras, una motivación para aplicar el concepto del punto anterior tiene que ver con la experiencia que le queremos brindar a los usuarios. Te voy a contar una anécdota de este proyecto: un amigo a quien le mencioné en lo que andaba abocado hace un tiempo atrás me respondió que era innecesario ya que con los avances en materia de comunicaciones, en un tiempo más iba a haber internet hasta en el desierto de Atacama y con eso hablar de offline sería innecesario. A ver: yo no tengo ninguna duda de que Internet ya sale hasta por los cajones de la mesa de luz (los que me tienen en su lista del messenger sabrán de las veces que me han encontrado chateando en el bus, porque no sé por allí pero acá hay Internet en los autobuses)
      Sin embargo, así como lo hay... deja de haberlo. Si por hache o por be el servicio no está disponible, pues agua y ajo. Me acuerdo meses atrás de un hotel que paré en Los Ángeles. Tenían internet gratis en las habitaciones, pero no funcionaba. Le hice saber al conserje y me dio las gracias (además de disculparse por las "inconveniences"). Y ahí quedó, no?
      Pero además, el concepto del browser como cliente universal me parece hasta cierto punto cuestionable. Sirvan las características del Reader contadas acá como ejemplo de cosas que el browser no provée per sé, excepto picar una batahola de código entre server-side y JavaScript (además de lidiar con manejo de sesión, escalabilidad, latencia de red, etc). Complicado de desarrollar, y una experiencia de usuario que en el mejor de los casos se va a arrimar. Son loables los progresos alcanzados con tecnologías RIA (por Rich Internet Applications) como AJAX o Silverlight; yo mismo escribí una serie sobre la web social (Web 2.0) enumerando patrones y tendencias actuales. Pero a cada cual según su necesidad: queremos algo disponible en cualquier plataforma en forma inmediata, sin necesidad de instalar nada? Tecnologías basadas en la web son sin duda la solución (y para ello lo más probable es que resignemos parte de la experiencia de usuario, y nadie se va a suicidar por ello si no había requerimientos de experiencia de usuario especificados de antemano). Queremos, en cambio, privilegiar la usabilidad, tomar ventaja de recursos locales (almacenamiento, otras aplicaciones disponibles, etc), reducir tiempos de espera (especialmente para descargar información que ya alguna vez habíamos descargado y no se había renovado)? Bueno, si la respuesta es afirmativa, ahí es donde la primera S de S+S (Software más Servicios) adquiere relevancia. Ahí está el Reader, pues
      Para cerrarte la anécdota que te contaba de mi amigo, es cosa de no creer pero justamente una vuelta me pasó con él que quiso dejar un comentario en un artículo de mi blog (para colmo justo un artículo de SaaS!!!). Se escribió todo un speech (interesante por cierto, creo incluso más jugoso que mi propio artículo), pulsó "Aceptar" para mandar todo el choclo y... "The site could be temporarily unavailable or too busy. Try again in a few moments." Todavía mi amigo se había enojado conmigo por eso, por tener mi blog en ese servidor, etc smile_regular Si me llega a pasar eso en el desierto de Atacama, la primera vicuña que se cruce es tapado

    La experiencia también nos sirvió (o me sirvió) para afilar mis cualidades de administrador de proyectos: no teníamos ni todo el tiempo del mundo ni tampoco un equipo de gente atrás apoyando. Teníamos, sí, el core que se había usado meses atrás con el New York Times y otros diarios que podríamos decir que incluía gran parte de la lógica. No obstante, no preveía soporte multilenguaje y por ende la persistencia de este estado (es decir, si cuando lo cerraste lo tenías en español, asumamos que es que lo querés volver a encontrar en la lengua de Cervantes la próxima vez que lo uses). Bueno, en ese tipo de cosas estuvimos trabajando este último tiempo

    Cómo de experiencia de usuario se trataba, hubo que tener en cuenta que hoy por hoy los usuarios mayoritariamente tienen Windows XP SP2, que no incluye .NET 3.0 (requerido ya que la aplicación está basada en Windows Presentation Foundation). Por tal motivo llevamos el análisis hasta ese ámbito: el instalador tenía que hacerse cargo de todo (controlar la presencia de los requisitos, instalarlos en caso de que no estén presentes, etc). Analicé MS Installer versus ClickOnce, qué pasa si necesitás que quien lo instala acepte un EULA (end-user license agreement o acuerdo de licencia de usuario final) y una larga lista de etcéteras. Bueno, no lo voy a contar todo ahora pero se viene un artículo al respecto de distribución de aplicaciones (escenarios -usuarios desconocidos vs usuarios de tu organización-; tecnologías -MS Installer, ClickOnce, scripting-; y demás)

    Para cerrar, y como incidencias reconocidas, nos han reportado ya algunos incidentes:

    • El Reader no detecta bien proxies (o no hereda, por caso, la configuración del Internet Explorer)
    • Si en una página de visualización hay más de una imagen que desplegar, de momento despliega sólo una. Es un issue del core y según me contaron los que trabajaron en él, lo tendrían ya resuelto (por lo que voy a incluirlo en la versión 1.0 a liberar en el primer trimestre del 2008)
    • La facilidad de poner comentarios o realzar textos no se puede, hoy, aplicar a imágenes
    • El envío de artículos vía mail, ni siquiera lo mencioné más arriba como característica porque no estoy conforme con lo que pude hacer
    • Lo mismo para la opción "guardar" artículos

    Bueno, y debe haber otras más que yo todavía no detecté (pero vos podés hacerlo fingerscrossed)

    El Reader versión beta está ahí disponible desde fines de Noviembre. Dos días después de su lanzamiento ya se podía leer una crítica en InfoQ: http://www.infoq.com/news/2007/11/aj-reader

    Joojojoojooojojojojojooooooojjooo!! Feliz Navidad!!! smile_party

    November 17

    Arquitectura de Software en Forma de Cuentito

      
    Video: Software Architecture for Academy Students 

     Leandro Doeyo,  ex director académico de plataforma .NET para América Latina y actual director a nivel global, me visitó los otros días con una consigna: me pidió que cuente el rol de un arquitecto y cómo se llega al mismo pero en una forma que sea entendible por estudiantes universitarios de entre primer y tercer año de carreras afines

    Como es ya no para América Latina sino para todo el mundo, hubo que hacerlo en el "latin" de nuestros tiempos smile_embaressed (que de "nuestros" no tienen mucho). Es muy extenso así que traduzco los conceptos más salientes. Parece que venía inspirado ese día, no sé qué me pasó

    La entrevista original está en Channel 8. Auspició Yerba Mate Taragüí

     

    • Arquitectura de Software es, quizás, un 20% de las líneas de código de tu aplicación. Pero un 20% que va a estar involucrado en el 80% de la ejecución posterior. Esto es un riesgo y a la vez una oportunidad. Riesgo porque si metés la gamba en ese tan sólo 20%, lo vas a sentir en el 80% del uso posterior que le des. La buena noticia, aún, es que corregir el error implica revisar qué pueda estar saliendo mal en ese no más de un 20% del código, y si lo lograste descular, el arreglo debería alcanzar nuevamente al 80% del uso que de esa aplicación se hace
    • Cómo empecé yo... Me acuerdo que cuando era chico, durante la irrupción de las computadoras domésticas (Atari, Commodore, etc), yo tenía una de las más limitadas (1) y por lo tanto el conjunto de juegos disponible para la mía era bastante inferior al de mis amigos. Probablemente eso me hizo ser más inquieto acerca de cómo los juegos eran construidos (2), de manera de intentar reponer el faltante por las mías. Y fue un desastre: por ejemplo, me acuerdo de haber intentado programar un Pacman sin tener ni idea de lo que una buena arquitectura de aplicación mandaba. Así, te imaginarás, mandaba todas las líneas de instrucción del programa en la medida en que se me iban ocurriendo, una atrás de la otra, todo pegado, todo seguido... Y se dió la lógica: el juego transcurría súper lento, los fantasmas terminaban traspasando las paredes...
      (Leando interrumpe) Bueno, estaba bien, no? Para algo eran fantasmas...
      (Risas) Esa podría ser una posible explicación de mi fracaso... digo, a modo de excusa, no? Pero lo cierto es que sí: mis controles vía teclado también eran atendidos tarde, así que yo también me llevaba puestas las paredes del laberinto, recién después la compu se apiolaba entonces me blockeaba pero para eso yo ya estaba en cualquier lado... Fallo general y con eso mi primera frustración, pero a la vez la más remota ocasión en la que sentí que quizás debería intentar seguir una carrera y convertirme en un programador profesional. Y aunque yo ni lo sabía exactamente, lo que intimamente quería era aprender a ser un arquitecto de software
    • Acerca de un escenario real donde se entienda mejor qué papel cumple la arquitectura en un software, tal vez lo pueda ejemplificar con este juego (3)... Si te fijás, la lógica de este juego tiene que preocuparse por el renderizado en tiempo real y para eso hay que hacer montones de operaciones de punto flotante en simultáneo, lo que seguramente te va a requerir cierta infraestructura base: una CPU de alta velocidad, un tocazo de memoria, no creo que zafes de una tarjeta gráfica con sus propias capacidades (4), también te tenés que encargar de reconocer los comandos vía teclado o quizás habilitando un joystick, controlar el movimiento de tus enemigos, las paredes y todo el resto de la escena, de manera de saber si te llevaste por delante algún objeto en tu camino, el sonido... Te podría seguir mencionando pero ya te hacés una idea del vagón de cosas de las que te tenés que ocupar. El rol del arquitecto, entonces, es bosquejar los planos de esta aplicación, de manera de lograr tener una clara idea respecto de dónde quedó cada cosa
    • (Leandro) O sea que como arquitecto no es que tengas, nada más, que planear los componentes de la aplicación sino además ubicarlos correctamente para que la complejidad global sea más administrable, extensible
      (Diego) Nunca más adecuadamente definido. Se trata de eso: de administrar la complejidad y convertirla en algo más simple de entender, sobre todo por quienes luego van a tener que lidiar con la programación durante su existencia
    • Yo no fui arquitecto desde el primer día sino que, mientras estudiaba una carrera de computación científica, conseguí un trabajo como desarrollador junior. Ahí me tocó programar todo el día. Más que nada aplicaciones comerciales. Desde ese momento, llamemosle como "arquitecto junior", ya tuve que ir empezando a plantearme mejores maneras de programar las aplicaciones, ya sea para que corran más rápido, también para que estén más preparadas para cambiar en algún futuro
    • En mi caso personal, ya llevo más de 15 años así, y hacete una idea cuando arranqué (más de 15 años atrás), lo que el estado del arte de ese entonces tenía disponible. He laburado con tecnologías que hoy ya ni existen, pero lo importante es que en la medida en que iba ganando chapa, iba metiendo la gamba, y obviamente, aprendía de esos errores. En realidad así era como crecía, de manera tal que la próxima vez -las veces que me dieron la chance de probar de nuevo- intentara hacerlo de una mejor manera
    • Después de algunos años, con lo ya adquirido, podíamos decir que era un desarrollador senior. Y desde ese momento ya me daban cabida para poder tomar algunas decisiones de arquitectura (5). También, para definir algunas normas respecto de cómo el código debía ser escrito, más que nada para que el resto de los desarrolladores, sobre todo los más junior, no caigan en los mismos errores que yo había caído cuando pasé por esa
    • El siguiente paso ya fue pasar a estrenar el rol de arquitecto. Y de nuevo, otra vez a cometer errores como forma de aprender. En realidad la frontera entre un desarrollador experimentado y un recientemente designado arquitecto es todavía borrosa. Pero podríamos decir que el arquitecto empieza a estar enfocado más en modelos, planes y el proyecto en general en tanto que el desarrollador sigue ocupándose más de la lógica y el día a día. Pero el desarrollador puede asistir al arquitecto dando su opinión sobre los planos, incluso le puede sugerir cosas al arquitecto basandose en lo que él conoce mejor respecto de lo que realmente las tecnologías pueden lograr cuando uno trata de usarlas. De manera que así fue conmigo: en un dado momento ya se me pidió que largue un poco el teclado y me concentre más en decidir cómo modelar ese 20% que iba a impactar después en el 80% de la ejecución
    • El arquitecto tiene que abocarse a aquellas cosas que la aplicación debe aportar como una característica general. Ejemplos de esto son rendimiento (performance) y escalabilidad, que si bien están relacionadas son algo diferentes. "Rendimiento" tiene más que ver con tus ganas de que la aplicación te responda al toque (acordate del juego que te estaba mostrando). En cambio "escalabilidad" tiene más que ver con la capacidad de tu aplicación para recibir una carga incremental de usuarios, administrando y sirviendo a todo el mundo al mismo tiempo
    • Para esto te va a tener que tocar interactuar con otro estilo de arquitecto: el arquitecto de Infraestructura. Este rol se encarga más de planificar el parque de hardware, la red, el software básico como el sistema operativo, la base de datos, y también herramientas de monitoreo que ayuden a controlar que todo eso funcione sin dramas. A este arquitecto no le concierne cómo las aplicaciones fueron desarrolladas o lo que las mismas hacen -en términos de negocio- sino que las ve más como procesos que deben estar ejecutándose en forma "saludable"
    • Esto implica mencionar un concepto importante que es el concepto de Sistemas de Misión Crítica. En términos de negocio, un sistema de estas características es un sistema que tiene que estar disponible cuando el negocio lo requiera. Si por hache o por bé no está disponible (llamalo rendimiento, capacidad, el servidor está abajo, etc), la capacidad operativa del negocio se va a ver seriamente perjudicada: por ejemplo, los empleados van a tener a empezar a trabajar a mano, lapiz y papel, sin acceso a la data. Cuando el sistema vuelva van a tener que reprocesar todo lo que les quedó colgado, y eso obviamente representa una pérdida de productividad
    • Al que quiera recomendación de lo que un arquitecto debe hacer, hay miles de cosas que sugerir pero si yo tengo que resumir en tres, me vienen a la cabeza las siguientes
    • Un arquitecto de soluciones programa todos los días (6), está en la cresta de la ola analizando las diferentes tendencias, probándolas. Programar a diario es una buena manera de estar "en forma"
    • Segundo, probá siempre varias alternativas. Cuestionate las que viniste usando ultimamente, preguntate si no podrá haber una mejor manera. Acá entramos en un terreno donde el pensamiento lateral puede aportar lo suyo, ya que plantea analizar todas y cada una de las variantes disponibles. Incluyendo esas que a primera vista parece que no van para ningún lado. En definitiva, tenés que entender las alternativas que funcionan, por qué funcionan; y las que no, por qué no y consecuentemente por qué deberíamos evitarlas
    • Y quizás la más importante: el software que dura es aquel que está preparado para cambiar. Parece un contra sentido, no? Sin embargo lo que quiere decir en los hechos es que si el usuario te reclama porque la aplicación está corriendo lento y vos descubrís que hay mucho acceso a datos y por ende vas a poner un caché, eso no te debería partir toda la aplicación por la mitad. Acordate siempre del 20%: ese 20% debería estar listo para cambiar cuando haga falta
    • Respecto de recursos relacionados con arquitectura, para poder ir manggiando el tema, fijate que el problema no es que no haya sino el opuesto: por donde empezar de todo lo que hay para ver?
      • La revista MSDN Magazine es sobre desarrollo de software, pero es a la vez la mejor manera de convertirse en un desarrollador senior (7). La revista sale en papel mes a mes, pero está disponible en forma gratuita en su web
      • Para los arquitectos de Infraestructura, la versión análoga es Technet Magazine, donde encontrás recomendaciones para afinar la marcha de Windows Server 2008, SQL Server 2008, etc. La versión web de esta revista, de nuevo: disponible gratis
      • Skyscrapr es el lugar para los aspirantes a arquitectos. En realidad su lema es "donde los arquitectos se convierten en tales"
      • Hasta acá te mostré aquellos sitios pensados para quienes aún no son arquitectos pero que quisieran serlo. Patterns and Practices ya es el sitio de las mejores prácticas de arquitectura, sea para calibrar aplicaciones, rendimiento, escalabilidad, El equipo detrás de este sitio también libera ejemplos de código que te podés descargar y ejecutar en tu propio entorno. Escriben, además, algunos libros que junto al resto son la mejor manera, para un arquitecto junior (8) para pasar al siguiente nivel
      • El sitio oficial de Arquitectura MSDN apunta ya a gente que viene practicando el rol. Contiene cosas de hoy y mañana, sobre conceptos y tendencias como Web 2.0, SOA, etc
      • Y si ya querés hablar del rango más alto de arquitectos, aquellos que están parados ya en la vereda del negocio, mirando a la tecnología que está al otro lado de la calle, viendola como habilitadoras del mismo, tenemos una revista, el Journal de Arquitectura,  a la que te podés suscribir gratis y te mandas la copia en papel sin oblar un níquel. En su portal, todos los números están disponibles en PDF
    • Mi primer sorpresa cuando de la facu salté a la industria fue que, lejos de encontrar que usaban los lenguajes que yo me sabía como C y Pascal, o incluso superiores como yo presentía, en cambio usaban COBOL y otras antigüedades que hasta ese momento yo daba por seguro que estaban muertas. Bueno, estaban vivas y coleando y me tuve que poner a estudiarlas yo si no quería terminar así. Sin embargo la facu cumplió, desde la teoría, con enseñarme aquella visión de la película que después tuve que contrastar con lo que las realidades en la industria me imponían
    • De esta manera quiero motivar a cualquier estudiante en la facu que termine la carrera, que venga a la industria y descubra él también esa delgada frontera entre la teoría y la práctica. Y de paso que nos muestre nuevas formas de pensar que nos permitan perfeccionarnos, a la vez que esté abierto para conocer lo que la experiencia ya enseñó

    _______________________________
    (1) La Texas, la TI-99/4A
    (2) Además de volverme resentido, envidioso, ventajero, rencoroso, mulero, bebedor, vividor y pituco
    (3) Quake II.NET, disponible con código fuente en http://www.vertigo.com/Quake2.htm
    (4) De manera de liberar a la CPU de todo el despliegue gráfico
    (5) Un desarrollador senior, no obstante, la mira desde lo que está programando hacia la aplicación en general. Un arquitecto la ve al revés: desde la aplicación como un todo hacia cada componente
    (6) O, equivalentemente, analiza código escrito por otros
    (7) En la entrevista dije erroneamente "arquitecto senior"
    (8) Vuelvo a decir "arquitecto senior" queriendo decir otra cosa

    October 31

    Alta en el Cielo / Había una Diskettera (Presentaciones Mías Ahora en SkyDrive)

     En  un mes particularmente seco en cuanto a contenidos de arquitectura (más bien en cuanto a su publicación, ya que esta vez juro que estoy produciendo como hacía tiempo no lo hacía) por una cuestión de timing no puedo mostrar dos perlas que -en lo que a mí respecta- están listas, terminadas, pero lamentablemente dependo de terceros y la maldita confidencialidad por lo cual si no está listo... no puedo revelar de qué se trata

    Entonces al menos quería ofrecer cosas ya hechas y preferentemente olvidadas pero todavía útiles aunque sea en un 60%, como una especie de confesión al estilo "sí, señoras y señores, fui yo quien dijo eso allá por el día tal del mes tal del año tal"

    Mis webcasts sobre MSF, SODA (no, Stereo, no), Arquitecturas Seguras pero también presentaciones que hice en Chile para Foros de Arquitectura (como los casos de AOP, Migración de Aplicaciones o Comparación de Procesos de Desarrollo) así como también algún que otro evento eventual que MSDN organizó en el Sheraton

    Algunas solo, otras con Pacachú, el Rupa o Patrick Mackay. Veo eso y tengo mezcla de sentimientos. Por un lado ganas de hacerlo percha no sea cosa que lo vean y digan "qué hambre este pibe". Por otra, "juah! Yo ponía eso!? Esto se tiene que saber!". Ganó esa opción

    También vas a encontrar papers que escribí para una conferencia sobre Procesamiento Digital de Imágenes, basada en la tésis con la que logré que me digan licenciado (gracias, muchas gracias). Pavadita de lugar dónde la presente: Nassau, Bahamas! (todavía me acuerdo y eso que fue en 1999, el siglo pasado). Y otra que se hizo en Dublin, Irlanda, sobre "Principios y Prácticas de la Programación Java" (juah! Java!? Quién te ha visto y quién te ve)

     

    Sí: todo eso pasó, todo eso se puede ver. Todo eso está en mi skydrive

    September 29

    Cómo Construir Frameworks (Sí, Leíste Bien: "Cómo")

     Una  de las etapas más trascendentes en la carrera de un arquitecto es cuando le toca diseñar su primer framework. Ese momento es tan importante para él -por tratarse del primer framework que él creará en su vida smile_regular- como riesgoso para el proyecto -por tratarse del primer framework que él creará en su vida smile_embaressed-

    Quiero en estas líneas parar un poco la pelota contando primero -y antes de abrir el Eclipse, el Visual Studio o cualquier herramienta de modelado UML- qué es lo que llevó a la consideración de usar frameworks (qué es lo que viene estando mal cuando no se aplican), qué vienen a mejorar los frameworks (cómo es la vida después) y cómo concebirlos una vez que nos hemos decidido a incluirlos

    En el Principio Era Dios. E Inmediatamente Después, los Fideos

    Los estadíos tempranos de la programación no preveían -porque, logicamente, era temprano smile_regular- ciertas buenas prácticas. Entendamos por buenas prácticas aquellas que permiten alcanzar un fin igualmente bueno (o, por oposición, las que permiten evitar o mitigar algo malo)

    Y qué era lo malo que ocurría en los primeros proyectos informáticos? Si se había tomado la decisión de -por ejemplo- almacenar los datos en determinada base de datos, o consumir alguna biblioteca de un tercero (para generar asientos contables, para tracear movimientos que eventualmente se pudieran auditar, etc)... el uso de esas APIs externas (la de la base de datos adquirida, o la contable o la de auditoría, etc) era directamente realizado in situ por los componentes de la aplicación. En todos y en cada uno de los lugares que esto era necesario 

    image

    Si te fijás en la parte izquierda de este diagrama, allí se concentra el código que vos (o tu organización, o bien terceras partes contratadas a tal fin) mantienen. Es éste el código que contiene la lógica de dominio de la aplicación, la cual no quiero llamar "lógica de negocio" para que no se malinterprete con "la capa de negocio" (que en este gráfico y por simplicidad vendría a estar inmersa en aquellas clases amarillas que se ven a la izquierda)

    Finalmente, es destacable que el código que vos mantenés no es que llame a cualquiera de los componentes de terceros que usás sino en realidad a aquellos que componen la interfaz de programación (API, por application program interface). Estos últimos se encargarán de acceder al interior del framework del tercero, ahorrándote a vos la tarea de tener que entenderlo todo

    Las contras hoy saltan a la vista pero voy a enunciar algunas acá (y seguro me voy a quedar cortina, debe haber muchas más):

    • Alto Expertise: empezar a usar las APIs nuevas no era para cualquiera. Había que entender detalles de bajo nivel de cómo fueron hechas (lo que se podía y lo que no, etc). Por consiguiente era común mandar a algunos empleados a un curso de entrenamiento en esta nueva tecnología, al tiempo de contratar en el mercado algún experto ya "bautizado a fuego" en las mismas (normalmente caro para la organización, pero a la vez seguro: iba a evitar que los demás se pongan a experimentar sobre la marcha). A posteriori, los que ya tenían cierto background armaban un entrenamiento rápido para el resto, y todo el mundo a picar código con las raras APIs nuevas
      Aprender nunca es malo, incluso es motivante!! Es necesario!! Lo que no es tan bueno es aprender bajo presión. No es tan bueno aprender para tener que usarlo en seguida (y bien) y por supuesto es bastante malo tener que estar en la misa y en la procesión (esto es, entender de la lógica de dominio de la aplicación y a la vez de las APIs externas que se están utilizando)
    • Acoplamiento Fuerte: de acá que en el título te decía "después de Dios, los fideos", porque a esto se lo conoce como código spaghetti o, en inglés, spaghetti code
      No sólo la decisión de ir con determinada pieza de terceros, sino también la forma en que ésta era usada era un candado a la mantenibilidad futura. Por ejemplo, te tiro un par de escenarios:
      • Después de los dos primeros años de uso de piezas de terceros, habiendo ya escalado su curva de aprendizaje, surgía la posibilidad de sustituirla por otra pieza de similar funcionalidad (por ejemplo la base de datos de otro fabricante, o cualquier otro mecanismo de almacenamiento de datos). La posibilidad de sustituirla podrá haber surgido, pero de ahí a concretarla ya era más difícil:
        • Los beneficios de la nueva plataforma debían realmente justificarlo ya que gran parte de la inversión hecha en la plataforma previa habrían sido tirados por la borda (quizás sin que todavía hubiera llegado su retorno o ROI, por return of investment)
        • Ir a revisar todas las líneas de código que tenían referencias a dicha API era un costo que normalmente, o bien se obviaba o bien se consideraba pero se calculaba mal (normalmente se pasaban por alto todos los programas regularizadores, tools de mantenimiento, etc, que usaban la API para regularizar cierta inconsistencia, y que por ende eran imprescindibles). Nada más ubicar todo este código era una tarea titánica, pero no tan titánica como modificarlo para referenciar a la nueva APIs (incluyendo testing, planes de contingencia, etc)
      • Incluso sin siquiera plantearse dejar de usar el componente externo, podía ocurrir -entre tantas posibilidades- algo como lo siguiente: como consecuencia de un problema de rendimiento o de escalabilidad, se decidía modificar la forma en que se venía usando la API. Por ejemplo, pasando un parámetro adicional que -según la documentación- mejorará las cosas. O, eventualmente, implementando una caché -y por consiguiente preguntando por resultados antes de invocar la API, o almacenandolos luego de invocarla-. Yo me acuerdo casi de memoria mega-operativos que duraban meses e involucraban a todos los responsables de módulos (Pagos, Servicios, Clientes, etc), los que tenían que notificarse de la modificación a aplicar y así garantizar que todos los programas fuentes bajo su responsabilidad quedasen afectados por ésta. Determinados operativos que recuerdo, inclusive, no podían pasarse a producción sino todo de una vez. Y esto generaba un rush (un quilombo, dicho en criollo) si en paralelo al cambio del operativo, algún programa fuente necesitaba otro cambio menor: había que asegurarse que el cambio del mega-operativo no entre a producción antes de tiempo (como polizón de otros cambios en paralelo). Un rush de la gran Wednesday

    Podría seguir enumerando contras pero creo que con las dos que mencioné (expertise y acoplamiento) ya tenemos suficiente como para amargarle el día hasta a los teletubbies

     

    Y Entonces Quedaron Tres: Tu Lógica de Dominio, los Componentes de Terceros y en el Medio Tu Framework 

    Para combatir estos problemas que te describía recién, es que surgió la variante de introducir una pieza en el medio que oficie de intermediario entre la lógica de dominio (la aplicación, bah) que tenías que construir y las distintas piezas de terceros (o sea, las que te iban a hacer la vida más fácil, pero sin complicartela demasiado)

    image

    Acá la mano cambia completamente, veamosla por partes:

    • Ahora la lógica de dominio no "habla" directamente a esas piezas de terceros que facilitaban trabajos genéricos y a bajo nivel (es decir, más allá del dominio de la aplicación). En cambio, la lógica de dominio habla con APIs contruidas por vos o tu organización, que abstraen el acceso a esas piezas de bajo nivel de manera que la lógica de dominio no sepa, en última instancia, quién va a llevar a cabo esas tareas
    • La lógica de dominio no le va a hablar a cualquier clase de tu framework sino particularmente a aquellas clases que vos expongas hacia afuera como lo que va a pasar a ser tu API
    • A su turno, esta API, sea por configuración o en forma dinámica, le va a hablar a clases internas a tu framework que son las que a su vez se apoyarán en APIs de terceros (esas APIs de terceros que en el esquema anterior eran invocadas directamente por la lógica de dominio)
    • Revisemos este último punto: la API de tu framework puede estar implementada internamente en forma múltiple, de modo tal que cambiando -por ejemplo- parámetros de configuración puedas optar por ir a una base de datos, o bien a un archivo XML, o bien a un servicio Web o a un componente accesible mediante CORBA, etc, etc... etc!! smile_teeth

    Los beneficios son mútiples, si bien no están excentos de algunas contras (ahora vamos a comentar algo al respecto). Como pros podemos enumerar lo siguiente:

    • Requerimientos de Expertise Reducidos (o Nulos!): como comentábamos antes, si incorporar una pieza de terceros implica lidiar con una API compleja y no excenta de terminar haciendonos meter la gamba, podríamos encapsular el acceso a la misma en otra API de complejidad simplificada (y quizás más ajustada a la lógica de dominio)
      Personalmente me gusta llamar, a este proceso de simplificación, comoditización (commoditization, tomando prestado un término de economía). En dos palabras, un commodity es un tipo específico de bien del que el mercado está saturado por lo que relanzarlo con cualquier factor de diferenciación no va a tener mayor impacto en la demanda. Los commodities -a excepción del petróleo, cuya producción suele estar al límite de la demanda- normalmente son baratos, más accesibles que otros bienes cuya disponibilidad es más limitada. Es por eso que me gusta robar este término de la jerga económica, ya que al encapsular detalles complejos de una API costosa de dominar en algo más simple, logra que un mayor número de desarrolladores pueda asir la nueva interfaz en plazos más breves. El código de estos desarrolladores, en tanto invoca a la API del framework, termina en última instancia invocando a la API externa
      El efecto neto creo que ni hace falta explicarlo: la ejecución terminó sacando provecho de la API externa sin que varios de los desarrolladores hayan debido pagar el costo de aprendizaje de la misma. Volviendo al ejemplo de la base de datos, toda la lógica de reservar un conector, abrir la conexión, ejecutar el acceso a la base y transformar los resultados a un formato más adecuado para la lógica de dominio puede ser encapsulado dentro de las fronteras del framework (en un rato voy a contarte, no obstante, de los riesgos de esto)
    • Lógica de Dominio Más Sencilla y Mantenible: es un corolario de lo anterior. Si toda la complejidad -necesaria en última instancia, aunque no relacionada directamente con lo que, desde el punto de vista del usuario, se espera que la aplicación realice- está escondida detrás de las paredes de esta plataforma que hacia afuera ofrece una interfaz más sencilla, la porción conocida como "lógica de dominio" -como consumidora que es de esta interfaz sencilla que el framework expone- dedica sus líneas de código más a esa lógica conocida como "de domin..." Caramba, que feliz coincidencia! smile_teeth
      Esta modularidad nos va a permitir también poder testear los componentes en forma unitaria (unit testing), práctica tal que afortunadamante hoy varias herramientas están disponibles -incluso en forma gratuita- para facilitar la creación de estas, así llamadas, unidades de testing
      Cuando de probar lógica de dominio se trata, las pruebas unitarias se llevan muy pero muy bien con otra técnica conocida como mocking (imitación), que también hoy cuenta con herramientas disponibles en cantidad y que nos habilita a simular recursos externos (la base de datos, un CICS transaccional allá atrás tirado en un mainframe, etc) de una forma rudimentaria. Esta claro que no son los originales pero si en realidad lo que queríamos en esta prueba unitaria era probar los componentes de dominio (los cuales sí deberán ser genuinos). Y toda vez que estos requieran acceso a otros componentes (sobre todo aquellos que sean complejos o bien en configuración o bien en ejecución o incluso en ambas), será allí donde el sustituto (el mock) entre en escena
    • Flexibilidad por Desacoplamiento: recién estaba hablando de mocking como una práctica que se veía facilitada por el hecho de que los componentes ganaban cohesión. Pero no es necesariamente el testing el que se va a ver beneficiado. Eso apenas en cuanto al ciclo de desarrollo del software. Pero el ciclo completo de vida del software incluye -claro- las piezas que están en ejecución. El hecho de que a través de toda la lógica de dominio usen componentes de un tercero (llamemoslo A) a través de un framework, permite que en paralelo podamos empezar a probar componentes alternativos de un tercero (digamos, B) con sólo reimplementar las interfaces que el framework, a través de su API, le exponía a la lógica de dominio!! Yo me voy a referir a esto en mayor detalle más adelante, cuando comente los patrones de diseño (especialmente Plantilla o TemplateEstrategia o Strategy). Por ahora que alcance don decir que no va a ser tan difícil cambiar de opinión respecto de lo que queramos tener allá al fondo ejecutando la lógica de bajo nivel (generar reportes, acceder a servicios remotos en forma transaccional, etc)
      Lo quiero ilustrar y dejar aclarado con el siguiente diagrama

    image

    Lo que estamos viendo acá es un escenario simplificado a diversos DAOs de la capa de acceso a datos. DAO (Data Access Object u Objeto de Acceso a Datos) se le dice al rol principal jugado por las clases de esa capa, que es el de llevar y traer cosas desde un repositorio, aunque desde una lógica funcional a la aplicación (por ejemplo, "traeme las Sucursales de Curicó", "los Clientes que deben más de tres cuotas", etc). Estos DAOs van a invocar, indirectamente, a una API externa que sea capaz de alcanzar al repositorio donde los datos son persistidos. Lo van a hacer indirectamente mediante una invocación directa al framework. Acá es donde se ve el beneficio del desacoplamiento: nosotros podemos probar ir por NHibernate, por ejemplo, que nos devolvería objetos planos o POCOs (por Plain Old CLR Objects). Eso nos ahorraría varias líneas de código de mapeo entre columnas de registros y propiedades de objetos. Ahora bien, si ese ahorro en tiempo de desarrollo luego se ve que se paga en rendimiento en tiempo de ejecución, podemos optar por sustituir el mecanismo de acceso por llamadas a procedimientos almacenados vía ADO.NET directo. Y para eso habría que tocar el DAO de cada módulo? No: como ya hemos eliminado el código spaghetti, la superficie de contacto con cada estrategia de acceso queda restringida a la implementación de la API de acceso a datos en nuestro framework. Encapsulada allí dentro y lejos del alcance directo de la lógica de dominio (estrictamente hablando se podría decir que los DAOs en realidad son híbridos, no pertenecen exclusivamente a la lógica de dominio; pero acépteseme aquí este abuso de confianza para no complicar demasiado las definiciones)
    Alcanza, decíamos entonces, con reimplementar la API mediante otra estrategia de acceso a datos y, seguramente mediante configuración aunque no sería el único mecanismo (como veremos más adelante), a partir de allí toda vez que desde la lógica de dominio se acceda a la API de acceso a datos, la nueva estrategia basada en ADO.NET tomará el control
    El día de mañana estos datos, o parte de ellos, están accesibles solamente mediante invocaciones a un sistema remoto (posiblemente en otra plataforma y/o ajenos a la organización) y entonces reimplementamos la API mediante invocaciones a servicios externos (por ejemplo a través de Windows Communication Foundation o WCF)
    No tengo interés en caer en la tontera o la falacia de pensar que implementar cada nueva estrategia y pasarla a producción es joda y se hace en una semana. Tengo claro, al revés, que una vez que el sistema esté en producción, introducir innovaciones de esta naturaleza no sólo depende de la factibilidad tecnológica sino del oportunismo (sea éste comercial, político a nivel de la organización, etc). Me pasó, admito que es así. Sólo quiero recalcar que, en el escenario sin framework que habíamos visto al principio -donde llamadas a sistemas externos se hacía in situ en cada lugar de la lógica de dominio donde era necesario, el costo de modificar la aplicación por la introducción de una nueva estrategia de acceso a datos podía tornar, la sola idea, una quimera incumplible que habría matado a tal proyecto antes de empezar

    • Reusabilidad: las partes complejas de la aplicación van quedando encapsuladas en componentes que presentan una interfaz más simple, más ad hoc (voz latina por "directo al grano") para lo que la aplicación realmente necesitaba de las piezas de terceros (más allá de todo lo demás que éstas ofrecían, que si se quiere aprovechar a la fuerza, se termina complicándolo todo). Estas interfaces simplificadas que el framework ofrece son más rapidamente aprehendibles por aquellos desarrolladores que necesitan enfocarse realmente en el agregado de valor (pero al nivel  de lo que el negocio requería para ayer), la habilitación de nuevos canales (PDAs, web, ATMs, etc) y otros beneficios que implican tomar lo que hay y simplemente accederlo desde nuevos puentes (construídos a tal fin). Me parece que no hace falta aclarar más (por favor, si me equivoco me lo hacen saber y lo aclaro) que los frameworks promueven el reuso de aquellas terceras partes complejas en una forma tal que, si el reuso no es alcanzado, el éxito mismo del framework pasa a ser materia discutible
    • Extensibilidad: el punto que sigue es crucial. No necesariamente todos los frameworks ofrecen esto que te voy a contar pero sí te aseguro que -cuando lo ofrecen- la ventaja de usarlos adquiere magnitudes de un orden exponencial. Extensibilidad es posibilidad que el framework te brinda de agregar nueva funcionalidad en una forma que quede enlazada al mismo. Por ejemplo, imaginate que te regalan un Scalextric (un clásico juego de la niñez de carreras de autos, visitá el sitio y lloremos juntos de la nostalgia). La caja que recibís ya viene con ciertas piezas listas para que armes un determinado conjunto de pistas. No obstante, vos podés adquirir piezas de terceros (el cuenta-vueltas, la chicana, autos especialmente preparados, etc) para agregarle emoción a la cosa. Incluso algunos que se dan maña se terminan fabricando sus propias piezas. Como fuera que las consiguieses, una vez que las conectabas a la pista, eran inmediatamente reconocidas y asimiladas por este "framework" que era el Scalextric
      Esto tiene un nombre y es el de Principio de Hollywood (Hollywood Principle), que establece una conducta de "no me llame: yo lo voy a llamar a Usted". Dicho, ahora sí, en lenguaje para informáticos, significa que si construímos determinados componentes respetando cierta especificación (implementando equis interfaces, extendiendo equis clases y, en concreto, poniendole lógica a equis métodos), cuando el framework esté en plena ejecución va a terminar llamando a nuestras extensiones, que van así a agregarle valor al valor que ya el framework le agregaba a nuestra aplicación. Pavada de círculo virtuoso! thumbs_upsmile_teeth
      No quiero acá empezar a apilar conceptos a lo pavote, sólo decir que si alguna vez oíste hablar de Inversión de Control (Inversion of Control o IoC, premio al mejor lector al que haya leído mi post de hará más de un año atrás), está relacionado con esto mismo ya que lo que estos frameworks van a ser ahora quienes invoquen métodos de tus componentes
      La llegás a ver? Vos o terceros provéen parte de la lógica de aplicación mientras que el framework controla la ejecución de la misma. Existe un rango de frameworks conocidos como Contenedores Livianos (de aplicación, en inglés Lightweigth Containers) que, basándose generalmente en archivos de configuración, instancian objetos de estas clases que vos creás, para pasarles referencias a las mismas a aquellos frameworks que las van a controlar. Este proceso se conoce como Inyección de Dependencias (Dependency Injection) y voy a referirme a él más adelante

    De nuevo, así como anteriormente al nombrar contras de no usar frameworks decidí no seguir enumerando, tampoco creo que valga la pena seguir mencionando beneficios aparejados por el uso de frameworks. Creo que todo el mundo a esta altura, haya comprado el concepto o esté en eso, está esperando lo principal: cómo se hace un framework!?

     

    Del Pensamiento a la Acción: Cómo Construir Frameworks 

    En esta sección voy a contarte aquellas prácticas que a mí me resultaron valiosas en las variadas oportunidades que tuve de construir frameworks propios, o las otras tantas que tuve de extender frameworks existentes. La mayoría de estas recomendaciones no han salido de mi cabeza sino que aparecen sobradamente en la literatura de hoy en día. Lo que sí son propias son las justificaciones de por qué estas prácticas valen la pena. Estas justificaciones no valen tanto por haber leído libros o white papers sino por haberlas comprobado empíricamente. Aquí están, éstas son:

    • Programación Basada en Interfaces (previamente Modeladas, claro!): ya desde el mismo modelado de procesos (generalmente a través de diagramas de secuencia en UML) se empieza a vislumbrar cómo las clases se van a ir relacionando. Pues bien, ya desde los tiempos del famoso libro Patrones de Diseño (Design Patterns, Addison-Wesley, 1995) de GoF (Gang of Four o la Banda de los Cuatro) se hacía mención a la ventaja de que si un objecto de clase A le tenía que pedir algo a otro de clase B, que entonces le hable en realidad a un objeto que implemente la interfaz IB en lugar de la clase B. Que, en todo caso, la clase B sea un implementación de la interfaz IB. La explicación es más que súper obvia: al no acoplar la clase A con la clase B directamente, si el día de mañana queremos, en una nueva clase B' rehacer los algoritmos de una manera más eficiente o al menos alternativa a la forma en que lo veníamos haciendo, alcanzará con hacerle llegar al objeto de la clase A la referencia al objeto de clase B', sin tocar absolutamente nada de la lógica de A (por el contrario, si la clase A tenía referencias explícitas a la clase B, entonces B' iba a tener que extender B -algo que no siempre va a ser posible si los métodos de B no son virtuales o, dicho en Java, llevan el modificador final indicando que no se pueden reescribir-. Acá se me puede achacar que entonces alcanza con hacer los métodos de B virtuales, de manera de siempre poder sobreescribirlos. El problema es que el creador de la clase B puede no querer que eso ocurra (por las razones que sea: porque viola el encapsulamiento de la clase, porque puede abrir la puerta a inconsistencias, etc)
      Las cuentas claras conservan la amistad: excepto que a la clase A le interese especialmente que sea un objeto estricta, garantizadamente de clase B quien le sirva, debería manejarse con referencias a objetos que implementan la interfaz IB y listo
      En la práctica, a veces como arquitectos estamos ya programando un cachito, generalmente haciendo una rápida Prueba de Concepto (Proof of Concept o PoC) y si nos dicen "wait, primero modelate todas las interfaces prolijamente, inyectactale a las clases A todas las referencias a sus interfaces IB para que no se acoplen, etc" se nos puede demorar mucho una PoC que sólo pretendía validar o refutar rápido una idea. Yo lo que hago en ese caso es darle para adelante como viene, sin complicarme demasiado la vida interfaceando al momento de la PoC, pero luego, cuando la PoC exitosa va a dar lugar a un código más limpio y desacoplado, aprovecho las ventajas de Refactorización (Refactoring, técnica para mejorar la calidad del código -en términos de claridad, mantenibilidad- sin modificar su comportamiento) incluídas en Eclipse o Visual Studio, que a la vez me permiten revisar las referencias a la vieja clase concreta B y sustiuirlas por referencias a la interfaz IB extraída
      Antes de dejar este punto quería comentar que algunos autores recomiendan aplicar esto no sólo con aquellas dependencias entre clases que se inyectan al momento de ser creardas, sino también en el pasaje de argumentos de entrada y salida o valores retornados de los métodos
    • Cuando Convenga, Limitar la Práctica Anterior a Clases Abstractas en lugar de Interfaces: ocasionalmente esa libertad que el programar contra interfaces (el principio anterior) te brindaba puede estar abriendo la puerta más allá de lo que te interesa que se abra, y quisieras poder poner ciertos límites allí. Por ejemplo, quisieras que cuando la clase A llame a la instancia de IB para que le devuelva un resultado, A pueda esperar que dicho resultado contemple que los argumentos que A pasó hayan sido validados, y además que el resultado venga formateado en una forma en especial (redondeado a dos decimales, etc)
      En esos casos la medida que se suele tomar es no definir la interfaz IB sino definir una clase B, abstracta, donde algunos de los métodos públicos ya vienen no sólo declarados sino también definidos. La sutil diferencia entre declarar y definir se remonta a los tiempos del lenguaje C: la declaración tiene que ver con los argumentos de entrada y salida, sus tipos de dato, junto con el nombre del método (función se llamaba en C porque existían en forma aislada: no pertenecían a una clase en particular). La definición, en cambio, es todo aquello que pongas entre las llaves { y }
      La clase abstracta B es tan solo una implementación parcial de la interfaz IB que no fue, y al igual que ésta, no se puede instanciar directamente sino que se debe extender una clase concreta B2, la cual deberá completar los métodos que falten (definidos como abstractos, claro, en la clase abstracta B). La clase A puede darse el lujo de no saber que B2 (o quizás B3, otra extensión de la clase abstracta B) es la clase concreta a la cual le pide métodos. Basta con que A sepa que está lidiando con una instancia de la clase abstracta B. Y acá empieza entonces la rebelión en la granja (y no precisamente la granja de servidores):
      "Ey, Diegum, pero eso viola el encapsulamiento en la medida en que A asume parte de lo que B hace!". La respuesta a eso es "sí, lo sabe y justamente porque lo sabe es que prefiere explícitamente acoplarse a esa funcionalidad parcial que B provée". La clase A todavía sigue siendo agnóstica del resto de la implementación hecha sobre la clase abstracta B que recibió. Se dice entonces que el grado de acoplamiento entre A y B es parcial, en la medida en que cualquier día podemos crear una nueva extensión de B y hacérsela llegar a A sin que A tenga que modificar su lógica (claro, excepto que A instancie -por ejemplo- B2 directamente y mañana queramos que use B3; los frameworks de Inyección de Dependencias ayudan a combatir esto, lo mismo que el patrón Factory -Fábrica- lo hace)
      Que A esté parcialmente acoplada con B, no es tan malo como estar totalmente acoplada (en el sentido que la superficie de contacto es menor) pero si -a pesar de que la clase A tenía la necesidad, de que B se comporte de determinada manera- tiene su parte fea: la clase B no va a poder modificarse libremente sino que deberá mantener el compromiso asumido con A y las restantes clases que confiaron en B por lo que B era en su momento. Como sea, esta técnica de usar una implementación parcial como una forma de limitar un poco la libertad que una interfaz sugiere es en verdad un patrón de diseño muy popular de GoF conocido como Plantilla (Template Pattern) o Método Plantilla (Template Method Pattern)
      La forma de garantizar que esos métodos que ya vienen definidos no puedan ser sobreescritos en una extensión de la clase B, se logra anteponiendo la palabra final a la declaración, si estás codificando en Java, o no definiendolo como virtual en el caso de C#. En otras palabras, por default en Java todo método se puede sobreescribir en tanto que en C# al revés: ningún método se puede sobreescribir a no ser que explícitamente el autor del método lo habilite
    • Mejor Aún: el Patron Estrategia (Strategy Pattern): si compraste la idea que vendí en el punto anterior, dejame por un adicional ofrecerte ahora el combo completo. Te planteo el siguiente escenario: vas al banco a pedir un préstamo. Les decís cuánta plata necesitás y ellos a partir de ahí te proponen prestarte ellos esa plata, ofreciendote determinados mecanismos para que a lo largo del tiempo se las devuelvas. Todos estos mecanismos se basan en algo obvio y básico: vos mes a mes (o con alguna otra frecuencia) vas a ir cancelando parte de la deuda, pagando un monto que se imputará total o parcialmente contra la deuda del capital que te prestaron y/o la deuda del interés -la ganancia del banco por el servicio de haberte prestado la plata-. A grosso modo, esto se llama amortización de la deuda, pero existen diversos mecanismos de amortizar. El más común y el único que conozco cómo funciona es el francés, donde empezás garpando mayormente el interés (ya que la deuda de capital está en su punto máximo, y por ende el interés es mayor) y un cachito de capital. Al siguiente período, como cancelaste ese cachito de capital, la deuda de capital es algo menor por lo que el interés que te devenga también es más bajo. Ahora, vos volvés a pagar el mismo monto que habías pagado el mes anterior, con lo cual se cancela primero la deuda de interés (que es más baja esta vez) y el remanente de lo que gatillaste (consecuentemente algo mayor esta vez) se imputa contra la deuda de capital, que así nuevamente descenderá y generará el mismo efecto al mes siguiente. El sistema de amortización francés suele terminar en una última cuota donde pagás un puchito de interés por el puchito de capital que te quedaba, y el resto se imputa contra la deuda de capital que termina quedando en 0 (cero). Existen varios otros sistemas de amortización: está el alemán, el americano... y calculo que habrá otros (una buena explicación de cada uno está disponible acá y en español)
      Podemos perfectamente desarrollar una aplicación para que el agente del banco te muestre el desarrollo de tu crédito, usando el patrón Plantilla. Simplemente definís en la plantilla la parte común a todos los sistemas de amortización (tienen una frecuencia, una cantidad de cuotas y una deuda de capital y de interés). Luego subclaseás esa plantilla con la parte variable de cada sistema (devengamiento de cuota, forma de imputación a la deuda de capital y de interés, etc). Tendrás así tantas subclases como sistemas hayas implementado
      El patrón Estrategia te ofrece algo más piola aún que lo que el Plantilla te da (aunque implementarlo es un cachito más complejo). Acá tendrás una clase fija Prestamo que es la que hace todo aquello que es común a los distintos sistemas, en tanto que aquellas cosas que cada sistema haga pero a su manera, Prestamo se lo va a pedir a otra clase que juega el rol de, así llamado, estrategia. (ojo, dije rol: la clase se puede llamar JosecitoPeñaloza si se te da la gana y el compilador te acepta eñes como caracter válido en identificadores). En realidad, Prestamo le va a hablar a una interfaz llamada, ponele, ISistemaAmortizacion, pero tendrá inyectada la consecuente dependencia a la clase que corresponda (SistemaAmortizacionFrances, SistemaAmortizacionAleman, SistemaAmortizacionAmericano, SistemaAmortizacionPizzeriaLasCuartetas, etc)
      La gran ventaja de el patrón Estrategia sobre el Plantilla es que, en este último las dependencias son estáticas: la herencia se declara en tiempo de desarrollo. Por consiguiente, si durante la ejecución de la aplicación, mientras el empleado del banco y vos discuten por el crédito, a vos se te ocurre probar con el sistema alemán qué pasaría, a nivel interno la aplicación tendría que instanciar la subclase de Plantilla que corresponde a ese sistema, pasarle todos los campos (duración de crédito, tu nombre, etc) y calcular el desarrollo
      En cambio con el patrón Estrategia mucho de eso no es necesario: a la clase Prestamo que tiene toda la data y la lógica en común le reinyectás la estrategia germánica y simplemente recalculás el desarrollo. Entonces se dice que la dependencia es dinámica, ya que es en tiempo de ejecución donde realmente se va a saber si tu instancia de Prestamo depende del sistema alemán o de Las Cuartetas (aguante, loco, quiero comer...)
      El patrón Estrategia hace gala de un principio de buena programación orientada a objetos ya postulado por el Gang of Four en el libro que te contaba antes) que dice "favorecé más composición de objetos que herencia de los mismos"
      Toma un poquito más de tiempo implementar el patrón Estrategia que el patrón Plantilla
    • No Abusar del patrón Singleton: normalmente cuando se habla de arquitectura de software o de sus técnicas en general, ocurre mucho que si quien habla (o, en mi caso, escribe) no es cuidadoso en la forma en que expone sus conceptos, estos pueden ser interpretados a la ligera -particularmente por arquitectos junior- y ser causa de problemas posteriores. El refrán típico para esto es "el que aprende a manejar un martillo le ve a todos sus problemas forma de clavo". Y eso te puede pasar con cualquier artículo que leas, si el autor no fue lo suficientemente explícito en contar los pros y contras, o efectos colaterales de algunas técnicas que -se esperaba- iban a beneficiar
      Quizás la memoria no me está ayudando pero realmente no recuerdo un caso más patente de estos tiros por la culata como el caso del patrón Singleton. Vamos a ver: el Singleton tenía como fin evitar una proliferación de instancias de clases cuando en realidad basta con contar con una, accesible desde cualquier lugar, para que todo el resto de la aplicación la pueda referenciar. Esto tenía como beneficio acotar el consumo de recursos
      El patrón Singleton fue recibido con beneplácito por todos quienes entendieron el beneficio que portaba, y comenzaron a aplicarlo (comenzamos, bah: yo vivía en el planeta Tierra también). A los pocos años, varios reparamos en las contras que el Singleton se traía bajo el poncho, contras que el libro de GoF no menciona
      Voy a contar la contra principal: el Singleton va a terminar acoplado a toda aquella clase cliente que lo use (con lo cual, cuanto mayor uso de esta instancia única, mayor acoplamiento) inhabilitando cualquier posibilidad de extensión al mismo por herencia. La razón? Para acceder al Singleton lo que se hace es llamar a un método de clase del mismo (normalmente llamado getInstance() o GetInstance() según se trate de Java o .NET). Dicho método pregunta a un campo privado -nuevamente de la clase (al ser método de clase, está claro que no podría intentar acceder a miembros de instancia)- si ya contiene una referencia a una instancia (que será devuelta ipso facto) o si aún contiene null (en cuyo caso le asignará una nueva instancia al campo de clase y devolverá su referencia). De esta manera, todas las clases que invocaron a ClaseSingleton.GetInstance() recibieron una instancia de ClaseSingleton. Si mañana por equis motivo tenemos que subclasear ClaseSingleton, todas aquellas clases que venían llamando a ClaseSingleton.GetInstance() seguirán recibiendo una instancia de ClaseSingleton así le agreguemos a la subclase su propio método de clase GetInstance(). Por consiguiente, o vamos a tocar en todos lados que llamábamos a ClaseSingleton.GetInstance() (incluí en la cuenta de las horas/hombre las horas de testing, integración, etc), o metemos los garfios directamente en ClaseSingleton (que es lo que comunmente pasa pero está completamente desprovisto de elegancia por cuanto para contruir algo nuevo necesité destruir lo anterior)
      La forma de evitar esta contra de los Singletons, sin resignar el beneficio que proveían en cuanto a control de instancias es mediante la aplicación de los Contenedores Livianos a los que me refería cuando hablé de Extensibilidad. Estos contenedores, como decía anteriormente, generalmente se basan en archivos de configuración donde declaramos instancias asignándoles algún identificador y qué clase queremos que nos instancie cada vez que le pedimos dame un objeto de identificador "pirulo". El contenedor liviano usa la data que pusimos en el archivo de configuración para saber qué clase va a instanciar (algo que va a lograr dinámicamente por reflexión). Normalmente los contenedores livianos nos permiten, en ese mismo archivo de configuración, indicar si queremos que devuelva siempre la misma instancia para un dado identificador, o si preferimos que crée siempre una nueva
      Algunos contenedores livianos, los más potentes, nos habilitan a indicar hasta cuántas instancias de la clase queremos que genere, y a partir de allí que devuelva siempre alguna de éstas. Los contenedores generalmente se basan en un archivo de configuración aunque ofrecen otros mecanismos para enhebrar las clases
      Normalmente el contenedor liviano es accesible a través de una clase estática del mismo, lo cual genera un acoplamiento sobre el contenedor liviano que puede ser dificil de revertir. Por esta misma razón los contenedores nos ayudan a minimizar la cantidad de invocaciones al mismo, enhebrando un tejido de referencias entre las clases de la aplicación. Esto va a permitir que, con tener la referencia a ciertas clases clave de la aplicación, las otras sean accesibles como propiedades de las primeras. Esto se conoce como Inyección de Dependencias y es el motivo del siguiente punto:
    • Cómo Enlazar las Estrategias: Inyección de Dependencias (Dependency Injection): volvamos al diagrama que te mostraba más arriba respecto de dónde está parado tu framework, cómo éste expone interfaces hacia afuera, que son la fachada de una implementación interna, de la cual las clases clientes del framework desconocen sobremanera (es decir, puede que tengan una referencia a las mismas pero ni siquiera saben de su existencia ya que la tratan como una interfaz o clase abstracta que el framework hacé pública). Asimismo, estas clases internas del framework se apoyan en APIs de terceros, eventualmente intercambiables (por ejemplo, tu framework expone una fachada de acceso a datos que en última instancia puede apoyarse en una API de conexión a bases de datos, o bien otra API de parseo de XML, o una tercera de interacción con un mainframe, etc). De nuevo, estas implementaciones de tu framework que se apoyan en piezas de terceros pueden requerir cierta configuración respecto de la forma de usar los mismos
      Cómo se puede lograr ese entramado de clases donde unas van delegando la ejecución en otras? Explicitando la pregunta: cómo hace la lógica de dominio para obtener referencias a clases de la API de tu framework, y cómo hace tu framework para saber concretamente en qué frameworks de terceros se está apoyando?
      Afortunadamante los contenedores livianos provéen ese servicio mediante la Inyección de Dependencias. De esta manera yo declaro al identificador "dao" como una instancia única de ADONETDao, (una hipotética clase de mi framework que se apoyaría en ADO.NET) y luego voy por sus propiedades, declarando su propiedad Conector como "oracle". En el mismo archivo de configuración, declaro "oracle" como instancia de la clase System.Data.OracleClient.OracleConnection. Luego voy por sus propiedades, asignando el string de conexión a la propiedad ConnectionString, y así sucesivamente. Capisce? No está una masa? Mañana puedo decidir pasarme de Oracle a otra base de datos, sustituyento en el archivo de configuración la propiedad Conector del identificador "dao" por, por ejemplo, "mysql". Ni siquiera tengo que ir a la declaración de "oracle" sino que puedo agregar a continuación una declaración "mysql" (puedo no: la voy a tener que hacer porque si no el contenedor liviano va a chillar por la referencia no resuelta), y a "mysql" le instanciaré las propiedades que el conector ADO.NET para MySQL me reclame (aún si no tengo un conector ad hoc, puedo ir por OleDb u ODBC)
      Del mismo modo, en el entorno de testing (en tiempo de desarrollo, claro), si quiero probar la lógica de aplicación sin entrar en el bolonqui de acceder a la base de datos que se va a usar en producción, puedo tocar la declaración de "dao", de manera tal que en lugar de ser una instancia de ADONETDao, lo sea de XmlDao. Posiblemente en ese caso sus propiedades sean otras, por ejemplo la propiedad "Repositorio" puede tener la ubicación del archivo XML que contiene los datos que voy a usar en mis pruebas
      Una masa total con un beneficio adicional: los usuarios de nuestro framework pueden implementar las interfaces del mismo en sus propias clases, extendiendo así nuestro framework allá donde nosotros no hemos llegado), enlazando luego sus implementaciones nuevamente mediante la Inyección de Dependencias que el Contenedor Liviano ofrece. Por ejemplo, pueden querer reimplementar las interfaces del objeto de acceso a datos con un componente que se apoye en NHibernate
    • Más Puntos de Extensibilidad: Callbacks (Retrollamadas) y el Regreso del Principio de Hollywood: hasta ahora veníamos viendo la extensibilidad por el lado de la implementación de interfaces, extensión de clases abstractas (mediante el patrón Plantilla) y la composición de objetos (mediante el patrón Estrategia). Otra forma de habilitarle a los usuarios de nuestro framework la extensión del mismo es mediante suscripción a eventos que nuestro framework emita, de modo que cada vez que nuestro framework emita esos eventos, notifique a los usuarios suscriptos al mismo
      El concepto detrás de esta facilidad viene dado por un patrón de diseño conocido como Observador (Observer), que afortunadamente la plataforma .NET implementa desde el mismo motor de ejecución, a través de dos tipos de declaradores: evento (event) y delegado (delegate). Para una discusión a fondo recomiento el capítulo 6 del libro "Programming .NET Components, 2 Ed" de Juval Löwy (O'Reilly, 2005). Eventualmente un interesante puntero al tema está en MSDN, pero el libro de Löwy es acabadamente lo más
      Se podrá notar que ésta es una particular forma de Principio de Hollywood, distinta a la que el patrón Estrategia podía plantear por lo siguiente: en el caso de Estrategia, la clase invocadora sabe que está pidiendo la ejecución de un método. Lo que no sabe es quién lo está ejecutando, pero sí que el método va a ser ejecutado. En cambio, en el caso del patrón Observador, cuando el evento es emitido, el emisor no tiene idea de cuántos suscriptores van a actuar en consecuencia. No sólo no los conoce sino que hasta podría no haber ninguno!!
      Obviamente, esto no lo hace ni mejor ni peor: Estrategia y Observador son dos patrones diferentes pensados para resolver problemas diferentes. Por caso, se ve claramente que Estrategia es una forma más potente (más cara de lograr también) de desacoplar, respecto del patrón Plantilla. Pero en el caso de Observador, la naturaleza del problema mandará si aplica Estrategia o si aplica Observador. Raramente se pueda optar alternativamente por cualquiera de los dos para un mismo problema
      Eventos y Asíncronismo: la gestión ante un evento mediante delegados se lleva idealmente bien con el principio de ejecución asincrónica. Y es lógico que sea así: justamente al ocurrir que el emisor del evento no sabe cuántos suscriptores van a actuar sobre el mismo, si el modelo de ejecución fuera síncrono ocurriría que el emisor se quedaría bloqueado hasta que el último suscriptor se entere de la ocurrencia del evento y actúe en consecuencia. En cambio de esta forma, el emisor del evento se puede quedar tranquilo que los que se hagan eco del mismo no le van a impedir continuar con el desarrollo normal de sus actividades
      Dicho en otro nivel, el usuario no se va a tener que quedar mirando con cara de tonto como la aplicación quedó congelada mientras en la barra de título de la ventana se agrega ese inoportuno "(Not Responding)" ("No Está Respondiendo"). Por esto mismo, el patrón Observador y la ejecución Asíncrona suelen llevarse como Cul... esteeemmm... como Evento y Calzoncillo quise decir. Quizás un principio de discusión sobre el tema está disponible en MSDN, aunque de nuevo te digo, conseguite el Löwy 2da Edición y revisá el capítulo 7. Eventualmente, otro artículo algo más en profundidad que el anterior de MSDN es éste
    • Monitoreo: tu Framework Debe Dejar Tomarse la Presión: una ventaja estratégica que los frameworks ofrecen como derivado son puntos de intercepción para poder monitorear lo que está pasando por ellos y con ellos. Por ejemplo, si te están preocupando las demoras en aquellas transacciones que acceden al mainframe, pero no tenés claro si la demora está en el tráfico en sí o en el proceso de marshalling de parámetros/unmarshalling de resultados que rodean -temporalmente hablando- al roundtrip. Existen varios mecanismos para implementar mediciones de rendimiento. Desde el dedazo en las clases del framework que implementan la conversación con el mainframe (recurso al que vas a poder echar mano si las clases son tuyas); hasta la gestión de los medidores en forma asíncrona como resultado de la emisión de eventos en las distintas etapas del acceso al mainframe. La primera alternativa es fácil de implementar pero tiene mucha pinta de spaghetti. La alternativa asíncrona es la más poderosa, pero es más bravita de implementar (igual, es la que te recomiendo por lejos). Una tercera alternativa es la que propone el patrón Decorador (Decorator) que, graficamente hablando, envuelve los métodos originales en una capa aislante donde va la lógica de medición de rendimiento. Es mejor que los fideos pero, al igual que éstos, agrega su overhead (sobrecarga). Sin duda que es más mantenible que los fideos, pero todavía es mejor la versión asíncrona. Otras alternativas de intercepción en frameworks son las que se describen en el libro "Enterprise Solutions Patterns" (MS Patterns and Practices, 2003)

    Y creo que con todo esto tenés como para entretenerte, si te acordás de tener en cuenta todas estas cosas, con el próximo framework que te toque construir. Acordate siempre que estas "pastillas" que te marqué recién se deben tomar en la dosis justa y no más allá. El que exagera la dosis y abusa de estos remedios suele terminar intoxicado. Pasemos entonces a las recomendaciones finales que se deben tener en cuenta antes de decidir crear un framework

     

    Antes de Empezar, README.1ST 

    • Retorno de Inversión (ROI o Return of Investment): las aplicaciones que no consideran frameworks suelen ser menos mantenibles en el largo plazo. No obstante, suelen ser también más rápidas de construir más allá de que sean pasibles de alto acoplamiento (cuando no también de baja cohesión). Seguramente un framework, pensando en el largo plazo, va a ser la decisión más acertada por la simplificación y mantenibilidad que ofrecen. Ahora bien, si la aplicación no está pensada para largo plazo sino para una etapa intermedia, gastar recursos en planear un framework es en realidad malgastarlos. A no ser que, ojo al piojo, el framework lo estemos pensando no necesariamente para esa aplicación sino ya pensando en un roadmap de aplicaciones que se van a beneficiar en serie (y en serio, como suelo decir en este blog) del reuso. Esto suena hermoso, aunque es difícil de lograr porque no es fácil anticipar de antemano las necesidades que clientes del framework van a requerir de éste. De esto hablé alguna vez en el post La Reusabilidad en Crisis. La batalla por el reuso total quizás algún día se gane, lo importante es no abandonarla
    • Procesos de Desarrollo Ágiles: así como hoy en día es muy común desarrollar nuestros propios frameworks, tanto lo es que queramos hacer esto siguiendo un proceso ágil como eXtreme Programming, SCRUM u otros. Sólo te quiero preparar, si ése es tu caso, para ahorrarte frustraciones posteriores: va a ser más difícil que eches a andar el framework si lo estás desarrollando con un proceso de los ágiles. La razón? Estos procesos se basan en la generación frecuente de entregables que el usuario empieza a testear a las pocas semanas de comenzado el proyecto
      Hacete la idea que, al menos en las primeras iteraciones, va a ser muy difícil que puedas meter demasiada lógica para el framework. Lo vas a lograr, en cambio, en el mediano y largo plazo y a través de un persistente proceso de refactorización (refactoring) como el que te hablé más arriba
      Por favor leéme bien: no te estoy diciendo que Agilidad y Frameworks son el agua y el aceite. Te estoy diciendo que en las primeras iteraciones va a ser raro que esta pieza clave que hacés para el largo plazo ya esté casi terminada en el corto
      Obviamente, esta mala onda que te acabo de tirar smile_regular aplica si tanto framework como aplicación mediante proceso ágil se deben hacer en simultáneo. Quiero decir, si el framework ya lo tenías, joya
    • Problemas de Rendimiento (Performance) y/o Escalabilidad: la ventaja del encapsulamiento que los frameworks alcanzan está en la reducción de complejidad para los desarrolladores que van a construir lógica de aplicación. Sin embargo a veces esto puede ser un arma de doble filo. Lo que te voy a contar que pasó, pasó de verdad en un proyecto del que fui parte. El framework con que contábamos allí había logrado que desarrolladores que no sabían Java desarrollen lógica de negocio en una forma completamente visual. Tanto el framework como la herramienta visual estaban hechas en Java por un equipo especializado (al principio el equipo del framework excedía en número al equipo de lógica de aplicación, pero en el mediano plazo -cuando ya el framework era más robusto y usable- la cantidad de desarrolladores no Java creció, en tanto que al tiempo, con el framework ya casi terminado, los desarrolladores Java iban de a poco siendo reubicados en otros proyectos
      Desde ese punto de vista, una masa: yo doy fe que lo que te contaba que los frameworks traen como beneficio, se confirmó acá (no fue el único proyecto en que lo comprobé, afortunadamente). No obstante, la clave del éxito del framework marcó a su vez su principal derrota: los desarrolladores no Java, desconociendo la complejidad no sólo a nivel de lógica sino en tiempo ejecución que transcurría en las capas interiores, usaban los servicios que el framework proveía como si fuera joda, provocando no sólo congestionamientos en los servidores sino también una baja capacidad de reacción del lado cliente, provocando la ira de los usuarios por la pobre experiencia ofrecida
      Ilusamente se puede creer que la clave del arreglo pasa por tocar el framework, poniendo cachés y usando otras técnicas adicionales para mejorar el rendimiento y/o la escalabilidad, pero eso es una parte de la verdad: va a ser muy difícil que, del lado de la lógica de aplicación, no haya que replantear parte de la forma de usar el framework. Cosas que pasan
    • Alternativas: los frameworks son hoy una forma muy elegante de generar aplicaciones a escala, pero no son ni por lejos la unica forma de hacerlos. Veamos que más tenemos, aparte de ellos
      • Generadores de Código: presentan la misma ventaja que los frameworks en cuanto a que la complejidad queda encapsulada para el desarrollador de lógica de aplicación, pero no va a estar encapsulada en clases del framework sino como resultado del parseo de un Lenguaje de Programación Específico de Dominio (Domain-Specific Language o DSL). A veces el desarrollador de lógica de aplicación ni se va a enterar siquiera de este lenguaje ad hoc, si encima tiene la suerte de contar con una herramienta visual que le ahorra la tarea de aprender siquiera esa sintaxis
        El ejemplo de estos días (por favor, no el único) es XAML, una sintaxis XML donde se definen ventanas, controles, etc, que decanta luego en clases .NET que realizan esto mismo
        Aquellos desarrolladores de ventanas que sus patrones estén dispuestos a desembolsar unos morlacos más, van a poder gozar de productos como MS Expression o similares, que visualmente le permiten arrastrar controles a ventanas u otros componentes, generando el XAML en forma automática (que a su turno será usado para generar el código C# equivalente)
      • Fábricas de Software (Software Factories): es en verdad no una alternativa a los frameworks sino un supra conjunto de estos, que además incorpora generadores de código para consiguientes lenguajes específicos de dominio. Al compilarse estos, llamadas al framework son generadas como resultado. Son superiores a los frameworks en el sentido que si estos estaban hechos en .NET, o en Java, entonces la lógica de aplicación debía programarse en el respectivo entorno administrado. Las fábricas de software, en cambio, permiten que el lenguaje específico de dominio se compile en .NET, en Java o eventualmente en ambos e incluso otros (Transact-SQL, etc) de modo de sacar el máximo provecho de lo que distintas plataformas de ejecución provean
        Las fábricas de software son lo mejor de lo mejor pero... son -por ahora- casi imposibles de lograr. Además no te librás de crear el framework si aún no contás con él
      • Programación Orientada a Aspectos (Aspect-Oriented Programming o AOP): es un paradigma que presenta una evolución respecto del hoy altamente afianzado "orientado a objetos". No obstante, de momento, como lenguaje de programación no termina de ser un experimento (AspectJ, un lenguaje AOP basado en Java pero con compilador propio; Aspect#, una versión análoga -aunque menos potente- basada en C#, etc)
        AOP permite combatir directamente el código spaghetti (que el folklore aopeísta llama "código enredado" o "tangled code") mediante la definición de puntos de unión (joint points) donde avisos (advices) son capturados por interceptores (interceptors) que dan intervención así a diversos aspectos (aspects). Casos típicos son logging, avisos para monitoreo, verificaciones de privilegios de acceso, etc

     

    Para Más Referencias

    August 22

    Objetos Inmutables: Se Mira y No Se Toca

     La  idea de este post surgió de casualidad, por una discusión que nada que ver -o, en realidad, aparentemente nada que ver- en el Foro de Arquitectura MSDN

    El que abría el debate preguntaba si era objetable adoptar como estándar de constructores de clase la llamada al constructor base, es decir el clásico
     

        public class Pepe : Juan
        {
    // ... campos y propiedades de la clase


    public Pepe() : base() // llamada explícita al constructor por defecto de la clase base { // ... lógica de inicialización de la clase }

    // ... sigue la definición de constructores y métodos de la clase
    }

     
    A él lo motivaba el hecho de que, al explicitar la llamada al constructor base sin parámetros (algo que de todas formas ocurrirá si no se explicita otra llamada a constructores de la clase base, los programadores iban a estar más conscientes de lo que iba a ocurrir entre bambalinas

    La discusión siguió y no viene al caso reproducirla (está disponible haciendo click acá si te interesa), pero la parte que yo quiero destacar, la que me pareció seria, es que -aunque el autor no necesariamente afirmaba pensar eso- todas las clases heredables tendrían que incluir el constructor por defecto (así se llama al constructor sin parámetros)

     

    A ver, repasemos el concepto: si a una clase A no se le define ningún constructor, por defecto la clase llevará un constructor cuya visibilidad será pública -public- en el caso en que la clase sea instanciable, y protegida -protected- cuando la clase sea abstracta

    Este constructor por defecto no recibe parámetros y, en ejecución, sólo llama al constructor sin parámetros de la clase base (que deberá existir para que la clase
    A compile normalmente)

    Por supuesto, esto no correrá si la clase tiene definido algún otro constructor que sí reciba parámetros. En ese caso, el constructor por defecto, para estar disponible, deberá ser explícitamente definido

    Más información en la especificación del lenguaje C# (apartado 10.10.4, Constructores por defecto)
     

    El problema de que una norma de buena programación conlleve a que todas las clases -al menos las heredables- lleven un constructor por defecto choca de frente con la posibilidad de tener clases inmutables (immutable classes)

    Qué son estas clases, para qué podríamos quererlas? Te lo voy a ilustrar con un ejemplo:

    Imaginate que estás trabajando en un proyecto grande donde tu equipo se encarga de codificar una parte y otros equipos se hacen cargo de otras partes, etc

    Suponete que tu equipo va a generar una API financiera que otros equipos van a usar, pero sin abusar (attenti, ahora te explico). Tu API, a grandes rasgos, consiste en una clase principal llamada Cotizador, con un método Cotizar() de las siguientes características
     

        public class Cotizador
        {
            // ... campos, propiedades y constructores de la clase
    
            public ICotizacion Cotizar(double monto, 
                DateTime fechaPrestamo, 
                DateTime fechaPrimerPago,
                int meses,
                double tasa)
            {
                ICotizacion cotizacion;
    
                // ... sigue la implementación, que en base a los argumentos
    // estima las distintas cuotas, con sus respectivas fechas de // vencimiento y el capital e interés cancelados en cada una return cotizacion; }


    // ... otros métodos de la clase }

     
    Concretamente lo que Cotizador.Cotizar() devuelve es una interfaz, ICotizacion, con las siguientes propiedades read-only (en seguida veremos por qué)
     

        public interface ICotizacion
        { 
            int Cuotas { get; }
    double Tasa { get; } double ValorCuota { get; } DateTime InicioPrestamo { get; } DateTime FinPrestamo { get; } ICuota this[int index] { get; } }
     
    Estimo que los nombres de las propiedades de ICotizacion son autodescriptivos. La interfaz prevé un indexador sobre las distintas cuotas, cuyas propiedades (de nuevo read-only!) son
     

        public interface ICuota
        {
            DateTime FechaVencimiento { get; }
            double CapitalCancelado { get; }
            double InteresCancelado { get; }
        }

     
    Te decía que las propiedades de ICotizacion y de ICuota deben ser de lectura unicamente porque si se pudieran cambiar una vez que el cotizador las creó, cualquier otra clase puede acceder a sus propiedades, falseando los resultados originales
     

    A ver si nos entendemos:

    • Pongamos por un minuto la PC en stand-by y pensemos en lo que una cotización representa
    • Una cotización es un documento, es la palabra de quien la otorga de que por un cierto plazo va a mantener una oferta de préstamo de dinero a cierta tasa, con determinado plan de pagos, etc
    • A nivel de negocio, por ende, una cotización es algo que no cualquiera puede manipular. Por ejemplo, si el cliente se está por ir porque rechaza la tasa de interés ofrecida, el agente puede ofrecerle una tasa menor hasta cierto margen
    • Si aún el cliente rechaza y a la financiera le interesaría no perderlo, ya debería venir el jefe del agente a proponer una tasa aún más chica
    • Está más que claro, por consiguiente, que si alterar una cotización, en la vida real, es algo tan delicado (y eventualmente no factible), en la vida virtual no debería permitirse que la tasa o la cantidad de cuotas o lo que fuere de una cotización se altere con una simple asignación "propiedad x = valor y"

     

    En este punto no falta quien me pueda tildar de exagerado, de que alcanza con avisarle a los desarrolladores que no deben cambiar los valores de una ICotizacion y sus ICuota una vez que fue creada y ya está. Pero mi punto no es ése

    Sin ser peronista, quiero citar una frase de Perón que decía "los hombres son todos buenos, pero si se los vigila son mejores"

    En proyectos grandes donde la gente viene y va, unos pasan, otros quedan, esas "puertas traseras" que uno va dejando en el código son las vulnerabilidades que pueden a la postre ser explotadas por quienes se propongan cometer fraudes

    Hay que salir al cruce de las mismas sin caer en tontos positivismos de "acá nunca va a pasar eso"

     

    Sólo para curiosos, incluyo una posible implementación de ICotizacion, en la que preferí usar struct en lugar de class, que me almacena en forma contigua en memoria el contenido de una cotización en forma consecutiva (si en cambio fuera una clase, lo que se almacenaría en forma contigua serían las referencias a sus campos. Fuera de eso no vas a encontrar nada paranormal, excepto quizás el modificador de acceso del constructor de la clase (internal en lugar de public, ahora te sigo contando qué es eso)
     

        public struct Cotizacion : ICotizacion
        {
            // campos privados
            private int cuotas; 
            private double tasa; 
            private double valorCuota;
            private ICuota[] vectorCuotas;
    
            // propiedades
            public int Cuotas { get { return cuotas; } } 
            public double Tasa { get { return tasa; } } 
            public double ValorCuota { get { return valorCuota; } } 
            
            public DateTime InicioPrestamo
            {
                get { return this[0].FechaVencimiento; }
            }
    
            public DateTime FinPrestamo
            {
                get { return this[cuotas-1].FechaVencimiento; }
            }
    
            public ICuota this[int index]
            {
                get { return vectorCuotas[index]; }
            }
    
            // constructor
            internal Cotizacion(int cuotas,
                double valorCuota,
                ICuota[] vectorCuotas)
            {
                this.cuotas = cuotas;
                this.valorCuota = valorCuota;
                this.vectorCuota = vectorCuota;
            }
        }

     
    Quiero que notes que en la estructura Cotizacion los valores de sus propiedades públicas sólo se pueden asignar al momento de construirla. Una vez creada ya no hay forma de alterarlos

    Por esto se dice que Cotizacion es inmutable (immutable). Se mira pero no se toca. El responsable de la clase (o de la lógica de negocio de este módulo) puede quedarse tranquilo de que, una vez que Cotizador.Cotizar() devolvió una instancia de Cotizacion, al menos esa instancia no va a poder ser manipulada o adulterada en ninguna forma 
     

    Este tipo de amenaza a la seguridad de la aplicación se conoce como Tampering o Violación de Precinto, según vimos hace poco más de un año en el webcast sobre Arquitecturas Seguras

     
    Lo de internal es algo tan revolucionario como polémico. Ese modificador de acceso indica que el constructor es público... dentro del mismo ensamblado. Con eso nos prevenimos de que nadie por fuera de Cotizador.Cotizar() crée una instancia de Cotizacion asignándole sus argumentos a las propiedades, y luego la cambie por la que nuestro método le había devuelto  

    La polémica se inicia cuando, como requisito, se pide poder persistir una Cotizacion (algo que seguramente ocurrirá). O más precisamente, la polémica se inicia cuando haya que recuperar una Cotizacion que se había persistido ya que, si la arquitectura de la aplicación separa la capa de acceso a datos en otro ensamblado... Cómo construir desde aquella capa las instancias recuperadas de cotizaciones?

    Entonces mejor lo volvemos a dejar público al constructor, pero ahora de nuevo corremos el riesgo de que alquien, en lugar de llamar al Cotizador, se crée una Cotizacion a mano y nos la haga pasar por buena! smile_baringteeth

    Parece el cubo mágico, no? Para armar una cara tenés que desarmar lo que tengas hecho de las otras. Cómo salir de aquí?

    Yo en verdad opté por dejar de lado el internal, volviendo a contar con un acceso público al constructor de Cotizacion pero impidiendo, vía Code-Access Security (CAS), que desde ningún ensamblado se lo pueda llamar, excepto el del módulo Cotizador y el del DAO de ICotizacion. Yo mostré CAS en acción en el webcast sobre Arquitecturas Seguras

     

    Si, como parecía plantear el participante del foro al principio, las clases tuvieran que tener un constructor por defecto (esto es, sin argumentos) de esa manera estaríamos obligados a definir las propiedades como lectura/escritura para poder asignar un valor inicial. Pero una vez que las propiedades son writables (sí: accesibles para escritura), el riesgo de tampering está presente

    Si bien la inmutabilidad (immutability) juega un rol clave en evitar tampering, debe ser aplicada junto a otras medidas que refuercen la barrera contra la violación de precinto a lo largo de todo el ciclo de vida de una instancia 
     

    Un par de datos más sobre inmutabilidad:

    • Por la forma en que las interfaces y las implementaciones del ejemplo fueron definidas, no es posible reimplementar la interfaz redefiniendo propiedades mediante el agregado de set(), ya que no compila si la interfaz implementada no tenía tal modificador. Del mismo modo, la estructura Cotizacion no se puede extender añadiendo setters a sus propiedades read-only, ya que éstas no tienen el modificador virtual que explicita la habilitación de sobre escritura. No obstante, no es mala idea que ciertos procesos delicados que van a trabajar con una Cotizacion recibida como argumento, se garanticen que su tipo se corresponda a su nombre fuertemente firmado (y no, por caso, una posible reimplementación trucha de ICotizacion)
    • El otro beneficio que tienen las clases inmutables es que, en escenarios de multitarea y concurrencia, al ser sus propiedades invariables no es necesario sincronizar el acceso a sus miembros mediante el comando lock(). Por consiguiente, serían un foco menos de generación de contención de hilos

     

    Será hasta la próxima (me voy al cobán a ver si me aprobaron el crédito)

    August 16

    -= 2 Años de DiegumZone =- Anuario 2006/2007 Para Coleccionar

     *** REGALO ANIVERSARIO: El DVD de Patterns & Practices 2007 con Todas las Software Factories, Guías de Arquitectura, Labos, Videos y Más!! ***

     Amigazos,  a Uds que léen siempre lo que tengo para decir, a aquellos que incluso se suscribieron a mi RSS para no perderse ni un post -incluso los que son más de ocio que de Arquitectura-, aquellos que he ido conociendo por sus comentarios sobre mis posts y que me encantaría tener la chance de conocer personalmente (tengo fé de que va a pasar), a los que me hicieron preguntas adicionales (y con eso me hicieron sentir importante por un rato)...

    A todos Uds gracias. El pasado 11 de Agosto (el sábado último) cerramos el segundo año de este blog que, si bien está lejos de ser lo que me gustaría que sea si tuviera más tiempo para dedicarle, sí puedo anticipar que tiene cuerda para rato

    A modo de balance voy a destacar los posts más salientes de cada mes

    Agosto 2006 Abrí el juego con una crítica a las arquitecturas demasiado by the book (de manual) con Un Viejo Antipatrón: "Too Much Architecture" (Demasiada Arquitectura) y los dolores de cabeza (o más abajo) que eso trae después en la práctica. Ni siquiera una vez que las cosas están en producción, incluso mucho antes (ya que quizás ni lleguen a ser puestas en producción)
    Septiembre A raiz de cierta confusión que se percibió en el foro de arquitectura MSDN (y que, en rigor de verdad, no yo sino el amigo Arnon Rotem Gal Oz se encargó de señalar) me dispuse, en Layers vs. Tiers: la Parábola de Shemp y Curly, a señalar similitudes y diferencias entre las arquitecturas en 3 capas (3-layered), 3 partes (3-tier) y la legendaria Modelo-Vista-Controlador (Model-View-Controller, hoy al parecer evolucionada en Modelo-Vista-Presentador)
    Octubre Respondiendo a un pedido del Ale Pacheco (también conocido como Pacachú, el arquitecto de Microsoft Chile), armé una pequeña presentación sobre Office Business Applications (OBAs, aplicaciones empresariales usando Office como columna vertebral) que desde Redmond se vio en directo en un Foro de Arquitectura en Santiago de Chile. Como consecuencia y para que no se perdiera, generé el post Office Business Applications (OBA): Office Agranda su Oficina
    Noviembre Julio, un gerente de tecnología con el que había trabajado años ha (en mis tiempos de Javero viejo) me planteaba algunas dudas acerca de si esto de que la orientación a objetos permite alcanzar reusabilidad era cierto o no, porque a él, según me comentaba, la probabilidad de reusar código en los proyectos de su gerencia era puro bluf. El tema me dejó pensando, revisé mi propio background en proyectos para ver situaciones comunes que se presentaban a la hora de definir código que se quisiera reusar, y lo que finalmente terminaba pasando. Lo plasmé en La Reusabilidad en Crisis
    Diciembre Como derivado de discusiones en foros acerca de si comprar tecnología de base o hacerla uno, y ese tonto mito de que lo que se hace por uno tiene costo 0 (cero) como si esas horas/hombre las pagase Antifaz, el tío de Anteojito, escribí Otro Viejo Antipatrón: Repudio de la Infraestructura (Infrastructure Repudiation)
    Enero 2007 El nuevo año me motivó a sacar la cabeza un cacho del agua y ponerme a estudiar mecanismos alternativos de razonamiento para los problemas de siempre. Los resultados de este análisis los compartí en un par de posts, el primero dentro del hemisferio "Algo de Ocio" del blog, ya que no habían menciones explícitas a TI. Se trata de Pensamiento Lateral: Creatividad para Salirse del Montón. Semanas más tarde corrí esas ideas al hemisferio azul en Cómo Juega el Pensamiento Lateral en la Arquitectura de Software
    Febrero Con algunos compañeros del equipo, y espontáneamente, Mandy nos entrevistó en Los del Equipo de Arquitectura de Microsoft nos Hicimos la Película para que demos nuestra visión del rol de arquitecto de software. Me parece que el señor Michael Platt, lord de la ingeniería de software, la rompió
    Marzo Retomando una discusión que había iniciado durante el primer año de ZonaDiegum acerca del desajuste por impedancia entre Objetos y Tablas Relacionales, destaqué en Mapeo de Objetos y Tablas Relacionales (O/R-M). Lo Que a Mí me Sirvió qué cosas me salvaron a mí de no perderme en esa ciénaga que, yo considero, está constituída por herramientas aparentemente poderosas conocidas "mapeadores entre objetos y (tablas) relacionales" (object/relational mappers). La polémica sigue
    Abril En Estos Programadores que No Cazan Una..., hice mi crítica (en el buen sentido) sobre el libro "Por Qué el Software Apesta" (Why Software Sucks) de David Platt. Dos meses más tarde tuve el gusto de estrechar su mano en el TechEd de Orlando (la conferencia top de desarrollo de software sobre plataforma Microsoft)
    Mayo Terriblemente influenciado por cierta literatura que había llegado a mis manos sobre, por un lado, tecnologías asociadas a Web 2.0, pero principalmente sobre las oportunidades de crear un nuevo tipo de valor, enlazando empresas en una forma que ni SOA se hubiera esperado, con consumidores que a su vez ayudan a generar un efecto red que potencia los resultados en beneficio de todas las partes, inicié la saga Enterprise 2.0: Web 2.0 Y A Cobrar
    Junio Durante el TechEd de Orlando me tocó, por un lado, ser chairman del track de Arquitectura y por el otro, cubrir en determinados horarios un panel de discusión sobre temas diversos relacionados con eso. La verdad que la experiencia me resultó enriquecedora y meritoria de ser compartida. Por esta razón dediqué un post a cada día de esa semana (el primero es TechEd 2007- 1ra Jornada, los subsiguientes están directamente vinculados)
    Julio En Enterprise 2.0: Parte 3- Que No se Retove el Usuario, promediando la serie iniciada en Mayo, destaco cómo ciertos avances en tecnologías web hoy nos ayudan a ganar mayor reacción y practicidad para que quien la use no la sufra. Fue mi primer acercamiento a Experiencia de Usuario desde un enfoque de Arquitectura de Software (no de un diseñador de interfaces de usuario, dominio en el que me sentiría más torpe e impreciso que Leonardo pintando a la Gioconda con guantes de box)

    Mientras escribo esto me quedo pensando en lo que contaba de esa semana en que estuve en Orlando, durante el TechEd, y no me puedo borrar charlas con algunos arquitectos que me decían "todo esto me parece muy cool, pero por darle pelota me pasa que lo que antes hubiera hecho en una hora -seguramente sin buscar que sea reusable, compatible con el futuro, modular, componentizable, etc- ahora me lleva no menos de tres y me queda una sensación incómoda de si no estaba mejor cuando hacía cosas que seguramente no me iban a servir para siempre, pero que en lapsos breves estaban andando"

    Qué amarga conclusión si se comprobase que todo esto para lo único que sirve es para convertir soft barato y presuntamente berreta (habría que confirmar esto último, ya que no necesariamente) en soft que promete mucho pero no concreta tanto, y cuesta valores saladitos (recursos humanos escasos o no siempre a la altura de los últimos avances; horas / hombre que, baratas o no tanto, finalmente terminan siendo muchas más que las presupuestadas)

    Estará yendo todo el mundo a SOA, realmente? O SOA es algo que genera curiosidad, todos quieren leer algo sobre, pero pocos están firmemente decididos a ir para aquel lado? Y los que fueron a SOA, habrán encontrado una bolsa con moneditas al final del arco iris? Tendrán arco iris, o todavía están esperando que aparezca cuando pare la tormenta eléctrica, granizo incluído, que amenaza con enterrar el datacenter?

    La verdad es que SOA, como todas las restantes tendencias son resultados evolutivos de intentos anteriores que por alguna razón fracasaron. SOA no es más que una respuesta desacoplada al CORBA de los '90

    Y REST, qué es? Es una salida elegante y liviana a escenarios donde las complejas extensiones WS-* de los servicios web no sean necesarias

    Algunas nuevas tecnologías llegan a ponerle la tapa al cajón de los intentos anteriores, en tanto que otras vienen sólo a complementar (a sumarse a) soluciones aportando una dosis de sencillez allí donde no hacía falta poner toda la carne a la parrilla

     

    Qué pasos debe dar un arquitecto para aconsejar determinada tecnología? Preliminarmente, mantenerse informado de las tendencias actuales (sin tomar todo al pié de la letra, sólo estar alerta)

    Posteriormente organizar una Prueba de Concepto (Proof of Concept, o PoC) para aquellas tecnologías que considere que verdaderamente van a permitir mejorar el soporte del área de tecnología a los objetivos del negocio (tanto por el aseguramiento del revenue como por la reducción de costos). La PoC es un primer filtro a las tecnologías testeadas, que le deberían permitir al arquitecto hacerse una idea de hasta dónde esta aparente solución no podría ser un nuevo foco de complejidad

    Si la PoC resultase exitosa el arquitecto puede aconsejar al líder del proyecto (eventualmente a la gerencia de tecnología) de invertir más en esa tecnología para una posible adopción (sea en un dado proyecto o sea a nivel estratégico en un portfolio más amplio de aplicaciones). La aceptación por parte del líder de proyecto y/o de la gerencia dependerá en qué tan hábiles seamos en mostrar que estas tendencias realmente van alineadas con objetivos de la organización. Va a ser difícil, si no, que nos suelten un mango (pasa que nadie se quiere quemar después, viste? Entendé eso primero y se te va a hacer la vida mucho más fácil)

    Si hay luz verde, se abre una etapa donde se debería capacitar tanto a desarrolladores como a profesionales de TI (infraestructura) en las tecnologías a aplicar, así como eventualmente contratar profesionales ya entrenados en las mismas (y, de ser posible, "estrenados" también: con experiencia)

    Personalmente creo que el arquitecto no debería competir con los desarrolladores senior a ver quién la tiene más clara en las nuevas APIs. Suele pasar esto en aquellas personas de carácter inseguro de sí mismas que temen verse desplazados por aquellos que dominan mejor las nuevas tecnologías, como si la visión de negocio detrás de las mismas -se las domine o no- no le importase a la gerencia. En cambio, el arquitecto debería aprovechar el training en las nuevas tecnologías para, con la ayuda de los desarrolladores senior, definir frameworks (componentes, generadores de código, etc) que permitan esconder la complejidad inherente de las nuevas tecnologías, de manera de adoptarla en una forma commoditizada. En castellano, esto significa poder montar un framework de componentes y herramientas que permitan hacer uso de APIs nuevas, complejas, por parte de desarrolladores de nivel intermedio -que quizás, con suerte, ni sepan que lo que están desarrollando termina haciendo uso de estas nuevas tecnologías-. En suma, el arquitecto juega acá un rol primordial en bajar todo lo que se pueda el costo de adopción 

     

    Balas de plata, ya lo había dicho Frederick Brooks Jr, no hay ni va a haber: aún siguiendo las tendencias más noveles, de las que haya casos de estudio exitosísimos por todos lados, nada nos garantiza que a nosotros nos deba ir bien también. La clave es no dejar de lado las reales motivaciones, en términos de resultados de la organización, de subirse a nuevas tendencias. El arquitecto que pasa demasiado tiempo con la vista baja mirando las tecnologías, y no la levanta cada tanto para mirar lo que la organización demanda es como el tenista que no mantiene en todo momento la vista en la pelota

     

    Y con esto dicho se inaugura DiegumZone Año III Birthday cake

    June 26

    Repercusión del Regional Architect Forum de Colonia, Uruguay

     En  el suplemento de Tecnología del diario argentino La Nación salió esta semana una nota relacionada con el Foro de Arquitectura para la Región Cono Sur (esto es, Chile, Bolivia, Paraguay, Argentina y Uruguay) realizado en Colonia los días 14 y 15 de Junio

    No se trató de una cobertura de todo el evento en realidad, sino del keynote brindado por Edu Mangarelli (el chief, el primer jefe que tuve en Microsoft -de hecho él me contrató- y quien posteriormente me relacionó con mi jefe actual) junto con Ezequiel Glinsky (mi seguro jefe si me quedaba como architect evangelist en Chile ya que Edu pasó a ser country manager de Microsoft Uruguay -yo le había empezado a decir chief por joder y resultó en serio!- y Eze tomó su lugar como gerente de Arquitectura para la región)  


    El chief (Edu Mangarelli) en acción, desplegando una de sus virtudes más reconocibles: hablar en público
    (Edu recibió tiempo atrás el premio a la excelencia académica por su trayectoria docente en la ORT Uruguaya).
    Detrás,
    Ezequiel Glinsky espera atento la ocasión de demostrar lo suyo

    La nota incluye un reportaje a Eduardo y Ezequiel, y está bastante bien siendo que ese suple de Tecnología en realidad está escrito para un público no experto en desarrollo de software (sino, más bien, consumidor de software). A la nota la sigue, fiel al estilo del diario de habilitar comentarios de lectores, una batahola de antimicrosoftistas alegando que, con la nota, Microsoft intenta adueñarse de la autoría de conceptos como Service-Oriented Architecture (SOA), que omite dar cabida al Software Libre, que quiere monopolizarlo todo, que le pagó al diario por el espacio de publicidad disfrazada de artículo, etc

    En fin, palo porque bogas, palo porque no bogas. Me acuerdo de clientes que visitaba y me decían "el otro día en el diario salió una nota del nuevo iXxxx de la empresa Axxle. Cuándo Microsoft va a tener algo así?". Pero cuando, como en esta nota, Microsoft sale en los diarios teniendo algo, resulta que es porque robó ideas, garpó el espacio, etc

    Y, como siempre, no faltó la acusación principal que se le hace al gigante del software: pretender percibir dinero a cambio del software que desarrolla. Sólo quiero decir a aquellos que, para levantar el índice acusador, deben demostrar antes que ellos no perciben salario alguno por el trabajo que realicen (si no somos todos piolas smile_zipit)

    June 08

    [Serie] TechEd 2007- 5ta Jornada (Clausura)

     Bueno  estimados, esto va llegando a su fin. A aquellos que hayan venido leyendo la serie desde la Jornada Inaugural (o incluso el Preludio) les quiero dar las infinitas gracias de tener tanto interés y paciencia en seguir mi prosa verborrágica no excenta de detalles innecesarios cuando no inoportunos

    El día, en lo que al track de Arquitectura se refiere, lo abrieron el consultor de Microsoft Jezz Santos y el finlandés Edward Bakker con una sesión acerca del estado del arte en Software Factories (término acuñado por el arquitecto Jack Greenfield que hace referencia a herramientas extensibles para generar código en lenguajes genéricos como C#, Visual Basic .NET, Java o cualquier otro, mediante Lenguajes Específicos de Dominio -Domain-Specific Languages o DSLs- y/o herramientas gráficas). Algo ya había comentado al respecto en la 2da Jornada
    En la sesión, Santos y Bakker contrastaron la definición original de Greenfield, respecto de lo que una Software Factory es, con la definición más ajustada a Visual Studio que el comité de Patterns and Practices elaboró ultimamente. La razón de este giro se debe a que Greenfield enunció su definición allá por el año 2004, como una visión de lo que Visual Studio o lo que se usase para desarrollar software debía brindar para acelerar el proceso y liberarlo de complejidad. En cambio, Patterns and Practices ha venido trabajando desde la liberación de Visual Studio 2005 (esto es, desde Noviembre de dicho año) en la creación de software factories específicas para aplicaciones web, servicios web, aplicaciones de escritorio y aplicaciones móviles. Por consiguiente la definición de P&P está actualizada a términos concretos que Visual Studio hoy permite poner en práctica (lo de Greenfield era algo más abstracto). Veamoslas

    "Una Fábrica de Software es una línea de montaje (de software) que configura herramientas extensibles, procesos y contenidos usando una plantilla de fábrica de software basada en un esquema de fábrica de software para automatizar el desarrollo y mantenimiento de las variantes de un producto arquetípico mediante la adaptación, ensamblado y configuración de componentes basados en frameworks"
    (Jack Greenfield, Keith Short, "Software Factories:
    Ensamblando Aplicaciones con Patrones, Modelos,
    Frameworks y Herramientas
    "
    , John Wiley & Sons, 2004)

    "Una Fábrica de Software es una colección estructurada de elementos de software relacionados. Cuando una fábrica de software es instalada en un entorno de desarrollo, ayuda a los arquitectos y a los desarrolladores -en una forma predecible y eficiente- a crear instancias de tipos específicos de aplicaciones con una alta calidad"
    (Equipo de Patterns & Practices de Microsoft)

    Como se puede apreciar, la segunda definición sugiere la idea de lo que podemos encontrar en las Software Factories hoy: casos concretos para desarrollar aplicaciones de escritorio, servicios web, aplicaciones móviles y aplicaciones web. Hace poquito contaba que estos ejemplos concretos de fábricas de software sirven para lograr, con pocas horas/hombre involucradas, resultados impensables si ellas no fueran utilizadas. Esto no quiere decir que sea imposible desarrollar esos tipos de aplicaciones con Windows Forms/Windows Presentation Foundation (WPF), ASMX/Web Services Enhancements (WSE)/Windows Communications Foundation (WCF), .NET Compact Framework y ASP.NET/ASP.NET AJAX respectivamente. Sólo que, para lograr resultados de la robustez que las software factories son capaces de brindar, hacerlo a manopla toma más tiempo

    Como contrapartida, el aprender a dominar estas software factories (sus wizards, entender los assets que despliegan, etc) lleva su tiempo. El que se toma ese tiempo y las domina, golazo. Pero el que tiene que empezar un proyecto con plazos acotados, no quisiera comprometerme con lo que voy a decir pero quizás sea más útil ir derecho con lo que se sabía del framework .NET. En cambio, hacer la inversión de aprenderlas como parte de una estrategia a largo plazo de desarrollo de aplicaciones empresariales, vale sobradamente la pena

    Volvamos a Santos y Bakker, a su presentación. La misma no estaba enfocada en las, hasta ahora, cuatro fábricas de software de Patterns & Practices sino que iba hacia algo más ambicioso: qué se necesita y qué hay que tener en cuenta para construir tu propia software factory! Hace pocos días yo establecía la distinción entre software factories horizontales: aquellas que sirven para robustecer el desarrollo de aplicaciones varios dominios específicos (por ejemplo, banca, manufacturas, entretenimientos, etc). Pero yo los otros días ponía un ejemplo de un lenguaje específico del dominio de la Odontología. En dicho lenguaje las comandos primitivos tenían que ver con PACIENTE, DIENTE, COBERTURA (médica), etc. De modo que los programadores en ese lenguaje ni piensen en ADO.NET, en WPF, etc, sino que se concentren en el dominio de la aplicación odontológica que hay que crear. Tener una fábrica de software que nos habilite esto implicaría tener una fábrica de software vertical, ya que no serviría para otros dominios (como banca, seguros, comercio, defensa, etc) que el de la odontología

    Santos y Bakker intentaron responder a la pregunta tiene sentido desarrollar ese tipo de fábricas? Y la respuesta, aunque sensata, decepcionó a más de uno (que luego lo reflejó en las encuestas): hacelo si pensás luego construir cinco o más aplicaciones basadas en esa software factory. Es decir, create una fábrica de software si pensás con ella desarrollar software a escala. La verdad? No me suena para nada descabellado ese concepto. Es más, me parece súper honesto de parte de los autores. Normalmente se hubiera esperado un "dale para adelante no más que te va a ir fenómeno. Vos haceme caso y usá esto que vas a ser Gardel". En cambio, no. Primó la sensatez y en el espíritu de Santos y Bakker el mensaje fue "con esto no vas a ganar seguramente en el corto plazo"

    Que es la misma historia que pasa con los frameworks y la reusabilidad, no? Si tenés que hacer en estos meses una aplicación, y querés construir un framework para reusar componentes y alivianar así el desarrollo grueso, dale que va. Pero ponele una expectativa correcta a ese framework, para saber asimismo cuánta energía deberías invertir en él: es para reusar componentes en esa misma aplicación? O, en cambio, es para reusar componentes incluso en una futura aplicación? En este último caso, tu framework ya pasaría a ser parte de una estrategia a escala. Por supuesto que, sea nada más que para la aplicación inicial para la que es construido o para el futuro, ambas alternativas son válidas. Pero no hay que dejar de tener en cuenta que si es para una sola aplicación, el retorno de la inversión de dicho framework va a ser menor y por lo tanto la inversión en sí no debería ser excesiva (quiero decir, que hacer el framework no te vaya a terminar costando lo mismo o incluso más que haber hecho el proyecto sin él)

    Bakker y Santos están hablando de esto mismo, de una manera muy honesta y abierta. Del mismo modo, agregan, es menester contar con un entendimiento acabadísimo del dominio para el cual se está por hacer la fábrica de software, y fundamentalmente contar con la gente adecuada, esto es, que tenga el perfil necesario para desarrollarla. Por último, hace falta tiempo!

    Al respecto de esto último ellos sugieren que desarrollar la software factory demanda entre dos y tres veces el tiempo que demandaría generar una instancia del producto que la software factory construye. Es decir, por ejemplo, si tomásemos esto al pie de la letra, quiere decir que desarrollar la Mobile Software Factory demandó entre dos y tres veces lo que hubiera llevado construir una ventana de aplicación móvil como la que esta fábrica de software produce. El retorno de la inversión (return of investment o ROI) llega al construir la tercera o quinta ventana de aplicación móvil con esta facilidad (ellos dicen que lo mismo valdría para cualquier software factory que te construyas. Es decir, si te construís una software factory que produce elementos XYZ, al generar el tercer, cuarto o quinto elemento XYZ con la software factory estarías recuperando la guita que te costó hacer tanto esa software factory como los tres a cinco XYZ que ya lograste generar). Ojo al piojo, pues

    Una conclusión personal, no es que la hayan dicho Santos y Bakker sino que yo la digo, es que crear fábricas de software puede ser adecuadísimo para empresas cuyo core business (negocio principal) es desarrollar software. Es decir, empresas que comercializan software, empresas cuyos ingresos se basan en la venta de software. Como construir ese software tiene un costo, y las software factories en el largo plazo alivianan ese costo, suena razonable crear fábricas de software para mejorar las utilidades. En cambio, siempre en mi opinión personal (esto no fue ni insinuado por los autores), si la empresa se dedica a un rubro diferente (es una compañía de seguros, etc)... construir su propia fábrica de software puede ser algo realmente costoso. Por supuesto que, yendo al caso concreto, habría que cuantificar esto que digo y ver si vale la pena o no

    Bueno, nuevamente volviendo a la sesión de estos dos amigos, destacaron las herramientas que existen hoy para generar fábricas de software. Acá entramos en una maraña de acrónimos (GAX, GAT, DSL, SDM, etc) que se han ido sedimentanto con el tiempo cuan capas geológicas unas sobre otras, y que aunque te parezca que sos el único que no sabe el por qué o para qué de cada una yo te aseguro que son varios los carlitos que las andan repitiendo todo el tiempo sin saber para qué catzo sirven. Yo traté de hacer un poco de geología acá, y llegué a la conclusión de que

    • Un Guidance Package (o Paquete de Guías) es un conjunto de plantillas (de lo que quieras: de un XML, de una ventana Windows, de un componente, ..., es cualquier cosa no terminada pero que sirve de molde para que la termines como te quede mejor), asistentes (wizards, ventanas que te permiten, a través de pestañas secuenciales llenar un formulario con info que te va a crear cosas a medida -cosas tales como archivos XML, ventanas, componentes, etc) y recetas (es decir, un chm u hipertexto equivalente con info piola como how-to's, consideraciones de plataforma y otras recomendaciones). Las fábricas de software se implementan, por lo tanto, con estos paquetes de guías. Entendiendo esto creo que no te va a costar nada ahora entender lo que sigue
    • Guidance Automation Extensions (Extensiones de Automatización de Guías o GAX) es un entorno de ejecución (runtime environment) de Guidance Packages para Visual Studio 2005. En otras palabras, lo vas a necesitar desde el vamos sea que quieras ejecutar una fábrica de software de algún tercero, como las de Patterns & Practices o que quieras ejecutar la tuya propia
    • Guidance Automation Toolkit (Set de Herramientas de Automatización de Guías, o GAT) es una paquete de guías para construir, a su vez, paquetes de guías que implementen Fábricas de Software. No es un requisito instalar GAT para ejecutar una software factory, aunque sí GAX
    • Domain-Specific Language (Lenguaje Específico de Dominio o DSL) es un concepto general que hace referencia a un lenguaje diferente a los lenguajes de propósito general como C# o Visual Basic. El dominio, como decía en el caso de las fábricas de software verticales, puede ser un tipo de industria dado, el reglamento de un juego de aventuras o de autos, fútbol, etc, un editor musical, lo que se nos ocurra. Hasta acá, no hay nada que sea inherente a Microsoft: el concepto de DSL anduvo dando vueltas allá afuera rato ha
    • Domain-Specific Language Tools (Herramientas para Lenguajes Específicos de Dominio) es un conjunto de utilidades disponibles dentro del SDK de Visual Studio que permiten implementar DSLs en una forma muy potente:
      • Mediante un diseñador gráfico es posible definir modelos de dominio
      • Mediante un archivo de configuración XML se puede definir un diseñador gráfico que va a permitir modelar visualmente elementos que la fábrica de software deba construir, del mismo modo que el editor de clases actual de Visual Studio permite crear el esqueleto de clases, o el editor de workflows de Windows Workflow Foundation (WF) permite crear flujos
      • Mediante plantillas de texto se puede instruir a Visual Studio para que convierta la definición gráfica (basada en el modelo de dominio) a código en un lenguaje de propósito general, que finalmente se compilará para producir código ejecutable
      • Con todo esto listo, los desarrolladores ya pueden trabajar visualmente en modelos gráficos que del resto se encarga la herramienta
    • Para una discusión efectiva de dónde encaja mejor GAT y donde DSL Toolkit, sugiero leer lo que Mauro Regio junto con Víctor García Aprea (de Clarius Consulting, un partner que tiene mucho que ver con la infraestructura de soporte a las fábricas de software) tienen para decir al respecto

    Santos y Bakker mostraron demos de estas herramientas en acción pero admitieron que están aún a medio camino, no del todo integradas entre sí. Aún así bosquejaron cómo el proceso de creación de una Fábrica de Software debiera ser, generalizando una solución particular en una primera implementación de referencia, la cual debería servir de molde para una plantilla de solución desde la cual crear la primera versión de la fábrica, usando luego esta última para generar productos que sirvan para refinar el modelo que permita bosquejar una nueva plantilla de solución, y así seguir iterando

    Los muchachos finalmente comentaron el roadmap para el futuro inmediato de las fábricas de software, y todos los esfuerzos no sólo de Microsoft sino de otros jugadores de la industria -como los argentinos de Clarius con su Software Factory Toolkit-, el VSIPFactory (una fábrica de software para crear extensiones a Visual Studio; VSIP viene de Visual Studio Industry Partners, o sea socios de la industria que crean extensiones específicas de Visual Studio), o el DSL Editor. Esto dio cierto panorama de que la forma de desarrollar fábricas de software, o al menos las herramientas que se utilizan a tal fin, se encontrarían en vías de cambio

    Definitivamente, lo desalentador al respecto de las SF es ver que están de momento completamente fuera del roadmap de Visual Studio. Al menos Visual Studio 2008 (hasta hace poco conocido por "Orcas") no hace mención de incorporar nada de esto by default (hago tan temeraria afirmación en el hecho de que el white paper sobre VS 2008, aparecido a mediados de Abril, habla de LINQ, de ADO.NET vNext, etc... pero ni una sola mención de DSLs, de GAT, ni mucho menos de SF). Lo poco que se menciona oficialmente de la versión siguiente a Visual Studio 2008 (de momento conocida como "Rosario") tampoco hace mención a soporte para crear o ejecutar fábricas de software. Debo concluir que el soporte para construir fábricas de software seguirá estándo disponible por separado en la forma de extensiones? Siendo que todo esto viene dando vueltas desde el 2004, que tres años más tarde el asunto todavía siga en veremos no me da la sensación de que haya una firme decisión de ir para aquel lado. Por caso, no le tomó tanto al Updater Application Block convertirse en ClickOnce

    Hay, más bien, un apoyo, pero no un encolumnamiento detrás de las fábricas de software como un paradigma estratégico. Sería un error concluir, entonces, que Microsoft le bajó el pulgar: la Enterprise Library de Patterns and Practices también ha estado dando vueltas por un tiempo largo ya y tampoco pasó a ser parte constituyente de .NET. Sin embargo, va a haber EntLib para rato y lo mismo creo que las software factories van a seguir ocupando cierto espacio en el "cosmos" de .NET

    Los amigos Santos y Bakker se despidieron, luego de dar su mensaje honesto y franco de qué es lo que está pasando y qué no está pasando con las fábricas de software, dejando cierta sensación de "esto debe estar buenísimo como idea... pero viene muy verde". La misma sensación que teníamos hacia fines del 2004, cuando Andrés Aguiar nos vino a visitar a Santiago de Chile y nos brindó una sesión sobre Fábricas de Software en un Architect Forum

    Personalmente creo que la pelota quedó picando claramente en la cancha de las empresas que fabrican software. Presiento que ellos, los que fabrican soft como actividad primordial, le van a sacar más jugo que nadie a estos Guidance Packages

     

    A la salida de esta sesión comenzaba mi último tiempo en el stand del Equipo de Arquitectura. Lo más relevante que tengo para destacar fue un muchacho que me preguntó por las tecnologías para interfaz de usuario que se están viniendo, pero principalmente cierta inquietud entre ASP.NET AJAX y Silverlight, ya que ambas caen dentro del rango de las tecnologías web. Aunque parezca que la cosa pasa por optar por una u otra, en realidad son tecnologías complementarias y, llegado el caso, ambas podrían estar presentes

    La fortaleza de AJAX pasa más por su habilidad de poder pegarse un pique hasta el servidor (gracias al objeto XMLHttpRequest) y traer cierto XML que luego, vía JavaScript pueda servir para actualizar partes de la página sin necesidad de cargar la página nuevamente (porque esto último no sólo consumía más ancho de banda: además introducía el compromiso de salvar cierto estado de la sesión, sea del lado del servidor -lo que podría atentar contra la escalabilidad-, sea del lado del cliente -mediante cookies que podrían no estar habilitadas- o añadiendo el estado como parte del requerimiento HTTP, que no sólo decanta en un consumo mayor de ancho de banda sino que además es un modelo de programación más complejo -aunque ASP.NET libera al desarrollador de esa plomería-). Este beneficio que AJAX trae redunda en la experiencia de usuario porque el navegador parece actuar de una manera más ágil a los requerimientos del usuario. No obstante, en términos reales, los controles que ASP.NET AJAX ofrece al desarrollador son controles que, en última instancia, se renderizan mediante el soporte básico HTML que los browsers poséen. Por lo tanto, cuando un navegador entre a un sitio desarrollado con ASP.NET AJAX, no va a requerir instalar nada adicional para poder aprovechar sus ventajas (en la medida en que su JavaScript tenga disponible XMLHttpRequest) ya que las bibliotecas de lado cliente de ASP.NET AJAX se descargarán automáticamente al estar vinculadas mediante el comando HTML <SCRIPT>

    Por el lado de Silverlight, la fortaleza viene dada en sus capacidades gráficas, que exceden las que los navegadores traen por defecto (basadas en HTML). Pero, justamente, para poder ir más allá que el default cada navegador deberá instalar un plug-in que le permita expandir esas capacidades (similar al plug-in para ejecutar applets de Java o animaciones Flash). El runtime de Silverlight que se carga en el navegador tiene una mini CLR (common language runtime, el motor de ejecución de .NET) embebida, capaz de cargar ensamblados y ejecutarlos. Este dato no es menor, porque si necesitamos llamar a un servicio web podemos usar el mecanismo de proxeo que .NET habilita per se, sin necesidad de usar el XMLHttpRequest de AJAX. La tecnología de visualización que Silverlight utiliza está basada en XAML (eXtensible Application Markup Language), el mismo de Windows Presentation Foundation (WPF) que se basa en vectores y permite, especialmente, dividir labores entre diseñadores de interfaz de usuario y desarrolladores de software (que son los que van a ponerle conducta a la interfaz que los diseñadores -valga la redundancia- diseñen). También, Silverlight permite embeber multimedia en las páginas

    Claramente que Silverlight puede vivir sin AJAX y no al revés. Pero como contrapartida, AJAX no necesita de ningún plug-in para correr por lo que, si no es un requisito diseñar una interfaz de usuario con características extra a las que provéen por defecto los navegadores, ASP.NET AJAX es una respuesta más que óptima. Escenarios típicos de esto son aplicaciones cuyos usuarios son externos a la organización (clientes, socios, proveedores, etc) que tal vez rechazarán instalar Silverlight sólo por correr nuestra aplicación (nada más pensá lo invadido que te sentís cuando un sitio web te dice que le habilites las cookies o le levantes la restricción de ventanas pop-up). Silverlight, en cambio, se me asemeja como más realista en escenarios de intranets y extranets cuando los usuarios son empleados de una organización y usan una infraestructura que la organización les da y administra por ellos. Hay que ver qué va a pasar si algún día Silverlight está tan desplegado como hoy lo está Adobe Flash (que a la fecha en que entré en este link, http://www.adobe.com/products/player_census/flashplayer/, indicaba que estaba en el 98.7 de los desktops)

    Te voy anticipando dos problemas que ya se van empezando a sentir, tanto con AJAX como con Silverlight:

    • Bookmarks: al usuario de la aplicación le da lo mismo si lo que está viendo en la ventana del browser es ASP.NET con AJAX o sin, Java Server Faces, Struts, Silverlight o lo que sea. Lo cierto es que, mientras va ejecutando la aplicación puede pasar que llega a un estado que quisiera conservar para futuras referencias. Por ejemplo: ve la leyenda "Aéreo confirmado con el código #236734GHAY29" y más allá de imprimir esa página, quiere bookmarkearla para poder volver inmediatamente a ella. Si estábamos trabajando con ASP.NET convencional, existía una manera de poder hacer que la página sea bookmarkeable mediante la adecuada generación de una URL que contenga los parámetros que siempre nos permitan volver a generar a generarla (en este caso con el código de reserva alcanzaría)
      Pero si veníamos haciendolo con AJAX o Silverlight donde la URL es la de la última página que se cargó completamente hasta que empezamos a darle al XMLHttpRequest o a Silverlight respectivamente, la cosa se va a poner más difusa para el usuario porque el bookmark lo va a hacer volver al inicio
    • El botón de Volver (back button). Suponete que, sea con AJAX o con Silverlight, el usuario selecciona un barrio de una lista y la aplicación le despliega las pelis que están dando en cines de ese barrio. Suponete entonces que no hay ninguna que le interese y que quiera probar con un barrio vecino. Tiene la chance de pulsar un link en la página que dice "cargar otro barrio" pero en cambio prefiere, porque suele no fallarle y está acostumbrado, apretar el botón de volver para pasar al estado anterior donde tenía que elegir barrio y ninguna peli aún poblaba la lista. Bueno, como diría Pepe Biondi, patapúfete: va a volver a la página previa a la última página que cargo completa

    No tengo ni idea sobre workarounds para estos problemas pero doy fe que proximamente los habrá en blogs, portales, etc

     

    En el durante, y ya cerrando el evento, Jeff Loucks brindó una sesión de Infraestructura acerca de cómo hacerle tuning al servidor Small Business Server 2003 para optimizarlo para aplicaciones típicas en entornos de 25, 50 y 75 usuarios. Loucks mostró cómo simular carga al Exchange mediante LoadSim, una herramienta parametrizable que simula que los usuarios están a full con el servidor de correo; lo mismo con Microsoft Dynamics CRM 3.0. También mostró cómo DiskPar, una utilidad que realinea los sectores de un disco puede ayudar a mejorar el rendimiento general. Mostró el clásico PerfMon que permite loguear el registro de actividades (tipicamente la actividad de los discos, el uso de la memoria y la CPU, la base de datos, etc). Del mismo modo mostró como simular -siempre con el fin de calibrar el sistema- transferencias de archivos masivas en el sistema

    Loucks mostró resultados de los benchmarks logrados luego de muestrear distintas configuraciones y explicó las conclusiones de los mismos

     

    Estimadísimos, esto ha sido todo. Esta semana me sirvió una barbaridad. El contacto con los clientes sin duda alguna que es fundamental -sirve no sólo para reconocer aquellas áreas de la arquitectura de software que uno debe reforzar porque se está quedando lisa y llanamente ignorante al respecto: también sirve para cuestionarse lo que uno crée que sabe y ser capaz de juntar todo para poder elaborar nuevas conclusiones-

    Al track, en sentido estricto, le fue bien. Respecto del año pasado se ha crecido no sólo en satisfacción sino también en asistencia a las sesiones. No obstante, hemos quedado lejos de otros tracks que han exhibido mejores resultados. Ahora me toca elaborar el post-mortem para determinar los puntos a mejorar en futuras ediciones (si es que me dejan seguir haciendo esto smile_tongue)

     

    Abrazo y gracias por leerme!!

    June 07

    [Serie] TechEd 2007- 4ta Jornada

     El  Jueves mi día comenzó al frente de la estación de demos, donde ya las preguntas se empezaban a repetir (obvio, preguntando gente diferente, claro). La más destacable es la de un caballero que se me acercó algo preocupado ya que me decía que los modelos de arquitectura que varias sesiones muestran parecen chocar entre si, lo que le daba la idea de que no hay una única forma de parar una arquitectura, sino que contextos diferentes parecían tener enfoques particulares

    Eso obviamente le generaba cierta inseguridad de tomar el camino equivocado, por lo que me preguntó "vos qué harías?" (juah! Número equivocado...)

    No, fuera de broma. Lo que le respondí es lo que realmente yo empecé a hacer hace ya varios años, cuando entendí que el paradigma orientado a objetos es mejor en aplicaciones monóliticas y ya no tan bueno en aplicaciones multicapa, principalmente cuando las capas están en procesos diferentes (posiblemente de servidores físicos también diferentes)

    La razón? Que al separar las capas lo que se busca es ganar cierta independencia, pudiendo mantenerlas por equipos diferentes y con ciclos de vida ocasionalmente coordinados, aunque no necesariamente (lo que permite ganar agilidad y responder más rápidamente a ciertos cambios de negocio)

    En cambio, al compartir clases entre las capas (con conducta, propiedades que los caracterizan a lo largo de toda la aplicación) la cosa se empieza a salir un tanto de cauce ya que cualquier clase que se es alterada implica puede impactar en todo el resto (no necesariamente cierto aunque con gran probabilidad)

    El asunto entonces pasaría por exponer servicios entre las distintas capas (suena a guitarreada pero la realidad terminó por imponer eso porque, se acepte o no, funcionó). Y mensajes deberían viajar entre las mismas, llevando objetos de transferencia de datos (data transfer objects, o DTOs), disponibles a lo largo de todo el caso de uso (quizás reusables entre unos pocos casos de uso, pero no ilusionarse con compartirlos a lo largo de toda la aplicación)

    Los servicios expuestos hacia afuera, internamente son llevados a cabo por clases que modelan procesos de negocio (casos de uso, basicamente hablando)

    Los mismos no deberían guardar estado, sino que trabajan sobre el estado del/los DTOs que hayan recibido en cada método (o servicio, si es que los llamaron de afuera)

    El hecho de que no guarden estado habilita a escalar la granja de servidores para cada capa sin mayor impacto en el código

    Es claro que el único caso en que se va a sentir impacto a ambas márgenes (capas, tiers, etc) es cuando el DTO a traficar deba llevar más datos. Pero siendo que el DTO debería estar limitado al caso de uso, eso ocurriría cuando la necesidad la tenga el caso de uso, con lo cual es más que súper razonable cambiar el mensaje de intercambio

    Ese por qué no se veía tan obvio, o al menos a mí no me gustaba, cuando el cambio se produjo en un caso de uso diferente pero termina impactando en todos los casos de uso perejiles que andaban compartiendo lo innecesario

    Poooorrrrrrrrrrrrrrrrrr lo menos, así, lo veo... yo. Más info al respecto he publicado alguna vez y hace tiempo acá

     

    Después estuve charlando un poco con un MVP muy particular, Jeffrey Palermo, acerca de lo complejo que es organizar eventos y que encima estos salgan a la altura de las expectativas de quienes pagaron por asistir... y de quienes cobramos también. Jeffrey, puedo dar fe, conoce del tema. El suele organizar unas fiestas muy tradicionales hoy, conocidas como Party with Palermo. El muchacho tira la casa por la ventana sin oblar un sólo níquel ni -del mismo modo- ganar metálico alguno a cambio. Cómo hace? Llama a editorial Wrox, a Apress!, a O'Reilly, a los productores AMD, MaxStore, Microsoft, y otros. A todos les hace aportar para la causa. A cambio, claro, de espacios de publicidad y el derecho a poner algún que otro stand con promotoras, etc. Qué tul, el amigo? Yo lamentablemente me perdí la que organizó para este TechEd (ver fotos) porque fue el Domingo 3 cuando los amigos de United me tenían en el Maelström

     

    En paralelo a todo esto, el amigo David Platt estuvo dando una presentación magistral -la que fue muy bien recibida en las encuestas- sobre la Arquitectura del Composite UI Application Block (CAB UI) y el posterior Smart Client Software Factory (SCSF) que lo incorporó como parte constituyente. La charla más que nada se enfocó a mostrar ejemplos concretos de bajo acoplamiento presentes en estas dos tecnologías sea para manejo de eventos, para la exposición de una interfaz de usuario (UI) compartida entre varias partes (conocidas como smartparts), para la disponibilidad de servicios que desde cualquier parte de la aplicación se pueden consumir y, por supuesto, para la configuración de todo lo anterior (sea vía XML, una base de datos remota, un servicio web inclusive). Cool

    Entonces llegó el turno de Scott Jamison, un arquitecto de Microsoft responsable de las aplicaciones basadas en Office, que resultó la revelación del track. Las claves del éxito de Jamison estuvieron dadas en el hecho de que abordó el problema por donde se lo debe abordar: las necesidades del negocio primero. En esta ocasión, Scott mencionó la necesidad de consolidar información de distintas fuentes (de manera que SOA pague por lo que fue) de manera de poner esas conclusiones no ya a la mano de gerentes sino de empleados en general. Información fácil de atajar para reaccionar con agilidad a los ritmos del negocio
    Y entonces encaró el problema como un arquitecto lo debe hacer, enunciando diversos posibles caminos y marcando de cada uno sus pros y contras. Entonces llega a uno de los puntos tabú de las aplicaciones empresariales: comprar versus construir. O "alivianar la carga y eficientizar la fuerza tecnológica para favorecer el negocio" versus "darle la chance a los empleados del área de tecnología de que hagan lo que más les gusta: contruir absolutamente todo (incluyendo las herramientas que sirven para contruir)". Jamison se volvó consistentemente por la primera opción, y destacó que la posibilidad de exponer funcionalidades desperdigadas en la forma de servicios web, habilita al consumo de los mismos desde componentes construidos para ensamblar Aplicaciones Compuestas, trazando entonces un paralelo entre las mismas y los servicios que ellas consumen
    Luego mostró cómo las distintas aplicaciones que integran 2007 Office System sirven como contenedores de componentes que consuman servicios web (o XML plano) para agregar otros tipos de valores, y lo sencillo que es construir componentes para estos contenedores de la plataforma. Y así calló en la cuenta de que Sharepoint Server encaja prolijamente en una nueva capa entre la de presentación y la de negocio: la capa de Productividad. La necesidad de la misma se funda en el hecho de que una capa de negocio tal como la conocemos aborda sólo aspectos funcionales de la aplicación que la contiene. Pero si a nivel empresarial tenemos varias de estas aplicaciones, las capas de negocio de las mismas están -en el mejor de los casos- débilmente conectadas, lo que hace que los usuarios deban usar más de una aplicación para satisfacer necesidades cruzadas (a veces, aunque no frecuente, en un mismo caso de uso)
    Así llegó una caracterización del Sharepoint, como plataforma escalable que permite exponer documentos como componentes que vinculan varias aplicaciones y que extender el alcance toma cortos tiempos de desarrollo ya que sólo se trata de construir puentes: no funcionalidades completas. Sharepoint provée per se no sólo administración de contenido (content management o CM) y colaboración sino también Inteligencia de negocios (business intelligence o BI) y principalmente capacidades de búsqueda (searching capabilities), entre otras características out-of-box
    Jamison destacó cómo eso es aplicable en forma de patrones. De diseño, sí, pero de negocio esta vez, de manera de componer aplicaciones con piezas (funcionalidades en la forma de servicios, datos en la forma de XML, etc) que encajen en estos patrones y ofreció ejemplos claros y concretos de ello. En cada uno de ellos, al final, mostraba el clásico diagrama de arquitectura en capas (presentación, negocio, datos y ahora también productividad), mostrando cómo 2007 Office System encajaba, para en dicho patrón. Por supuesto, no eran ejemplos de Powerpoint sino que Scott tenía demos ya construidas que analizó en vivo
    Al final de su sesión se dedicó a firmar ejemplares del libro "Essential Sharepoint 2007 - Delivering High-Impact Collaboration", que escribió con Mauro Cardarelli y Susan Hanley (Addison-Wesley, 2007). Aunque su sesión, por el tema que abordaba, no convocó masivamente, el público que asistió marcó en las encuestas un alto grado de satisfacción (8.29 de 9). Necesito más scottjamisons para este tipo de eventos

    Entonces tocó el turno de David Clark, un arquitecto de infraestructura que, al igual que Jamison, trabaja para Microsoft (y al igual que los restantes presentadores de Microsoft, siendo Jamison la excepción que confirma la regla, no le va tan bien como a los oradores no Microsoft -algo que ya habíamos previsto al armar la agenda, privilegiando a los no Microsoft; la expectativa que se genera es diferente cuando el speaker pertenece a Microsoft, ya que deja de importar cómo se llama sino que para quién trabaja pasa a ser lo más relevante y por ende se espera algo que realmente provoque un sacudón; cuando el orador es independiente, es decir, no trabaja ni para Microsoft ni para ningun otro de los grandes jugadores, lo que menos importa es para quién trabaja-
    Clark habló de Zero-Touch Provisioning (ZTP), un mecanismo para configurar desde cuentas, hasta workstations, servidores, servicios, software en general e incluso hardware (no sólo notebooks o PCs, también PDAs, impresoras, etc), con una mínima intervención humana (posiblemente nula), delegando las acciones en políticas (policies), scripting y otras facilidades otorgadas por Windows Server
    El resultado neto implica una ganancia en seguridad y eficiencia (casos típicos, cuando un empleado deja la organización y hay que revocar todos los derechos de acceso a aplicaciones en múltiples sistemas, etc). Una arquitectura completa dentro de la plataforma Windows le da cabida a Biztalk Server (que va a ejecutar el workflow de actividades),  a Active Directory (donde los permisos van a quedar almacenados) a MIIS (Microsoft Identity Integration Server, cuya versión compatible con Windows Server 2008 pasará a llamarse Identity Lifecycle Manager), quien se va a encargar de interfacear con sistemas externos, a Sharepoint Services (útil para la capa de presentación integrada) y, por supuesto, a .NET (el vehículo que transforma estímulos en comandos); también habló del roadmap de ZTP, el rol que va a jugar PowerShell (el mecanismo de scripting que sustituye a Visual Basic Script), el rol de .NET 3.0, de Windows Server 2008...
    En fin, me encantó a mí -personalmente hablando- la sesión, sus contenidos, sus demos, la forma en que se estructuró, sus porqués...
    ... pero el público le dio la espalda. La ley de Murphy para los oradores que pertenecen a Microsoft se volvió a cumplir acá
    Clark explicó definiciones para novatos, mostró workflows de cierta complejidad, contó cómo todo el arco de la infraestructura Windows se tensa para lanzar la flecha del aprovisionamiento lo más lejos posible (la metáfora es mía)... Qué querés que te diga: cuando esta sesión esté disponible, vela por favor. Te va a sorprender, te va -por supuesto- a gustar, y te va a instruir de cómo tu organización puede ganar en seguridad, eficiencia y productividad en lo que a infrastructure deployment (despliegue de infraestructura: hardware y software de base) se refiere

    Durante la tarde, Beat Schwegler (un arquitecto de Microsoft Suiza que manejó la agenda del track de Arquitectura para el TechEd Europe 2006 en Barcelona y logró el primer puesto! smile_omg) nos dedicó una sesión sobre cómo lograr googlear, dentro de nuestra organización, datos contenidos en nuestras aplicaciones. Una forma más de ver Inteligencia de Negocios (Business Intelligence o BI). Beat, en realidad, estableció las diferencias entre googlear en la web y googlear en la empresa. En la web cada server es un nodo (node) y un link en una página web es una conexión entre nodos, por lo que el problema de clasificar la información de la web pasa a ser un problema de matemática discreta. En la empresa, en cambio, la info está no sólo en nuestras propias aplicaciones (on shore) sino que puede estar en sistemas externos (off shore). Además, según cada quién, los usuarios buscadores no somos todos iguales: según que el que busque sea un empleado del front desk o uno del back office, la info debería agruparse y rankearse en forma diferente (y seguramente las experiencias de usuario pueden llegar a diferir de acuerdo al contexto de trabajo -usuarios en la calle con dispositivos móviles, usuarios en la oficina en un puesto fijo, etc-). Hay que lidiar no necesariamente con páginas web sino con datos que a veces están estructurados (bases de datos), semi estructurados (archivos XML) o no estructurados (documentos, mails, planillas de cálculo, etc)
    Entonces, ya en el plano de las propuestas, Beat mencionó "la" plataforma para aplicaciones empresariales que habilita búsquedas libres para información no sólo en bases de datos sino también detrás de servicios web o archivos propietarios, incluyendo la posibilidad de definir señaladores (bookmarks). Mostró asimismo la arquitectura de tal plataforma (con servidores de consultas directamente accesibles por los servidores de aplicación, pero a la vez dependientes de los servidores de indexado sobre las fuentes de los datos)
    Y lógico, cuando dijo el nombre de la misma, 2007 Office System, en seguida salió a atajarse del rechazo que les genera a algunos la sola mención de Sharepoint como contenedor de aplicaciones web, ya que consideran que Sharepoint provée una interfaz de usuario muy fría (y -presumen- poco configurable). Al respecto Beat mostró, y yo te invito (desafío en realidad) a que la veas vos también, la aplicación que Hed Kandi -sello discográfico inglés especializado en música house- creó sobre Sharepoint más ASP.NET webparts: http://beta.hedkandi.com/ (posta, eh? Esta versión actual maneja la multimedia en el browser todavía con Adobe Flash, pero ya se proyectan hacer uso de Silverlight en un futuro cercano). Esta aplicación, mientras tanto, hace uso de los workflows de contenido que Sharepoint habilita crear, así como también de sus mecanismos de búsqueda, sus Business Data Catalogs (BDCs, un mecanismo que permite pluguear información de fuentes externas -las que comentaba antes- de modo que Sharepoint pueda operar sobre ella), la interfaz de usuario extensible vía webparts ASP.NET, el formato de datos OpenXML y la seguridad que provée la plataforma
    Beat mostró los mecanismos de indexado sobre BDCs para facilitar las posteriores búsquedas de información, y las consiguientes estrategias de llamada al búscador (sea por una URL con parámetros HTTP GET, sea por suscripción a un RSS de búsqueda -o sea, un RSS que va agregando los posibles resultados que la búsqueda arrojaría a lo largo de la vida de la suscripción-, sea mediante la invocación de un servicio web -mecanismo adecuado cuando "quien" va a buscar es un proceso y no una persona)
    Mi opinión personal? Aquellos que vean la oportunidad en construir aplicaciones que habiliten búsquedas sobre su información, van a comenzar a hacer que la montaña empiece a ir sola hacia Mahoma

    La jornada se cerró con Mark Pollack y Rod Johnson (project manager de la versión .NET del framework Spring y padre de dicho framework, respectivamente). En su sesión -de la cual debo admitir, yo tenía gran expectativa- comentaron acerca de lo complejo que resulta desarrollar aplicaciones sobre las plataformas básicas como Java EE o .NET, la necesidad de contar con frameworks que levanten el nivel de abstracción y habiliten montar aplicaciones sobre ellos, mediante extensiones basadas en objetos planos (esto es, no casados con ninguna API o plataforma), de modo de acelerar los tiempos de desarrollo, mejorar las condiciones para un testing unitario de cada uno de sus componentes, etc
    Así destacaron las cualidades aportadas por Spring.NET, para configuración de aplicaciones (con características propias de un contenedor liviano -o lightweight container- ya que permite tomar sólo lo mínimo indispensable y nada más, no es una solución todo-o-nada ni obliga a extender APIs propias que inutilizarán la inversión si el framework un buen día es reemplazado
    También, mostraron cómo Spring.NET habilita AOP (Programación Orientada a Aspectos -Aspect-Oriented Programming-), un modelo liviano de programación para acceso a datos, a servicios middleware como ser colas de mensajería, a ASP.NET e incluso a frameworks open source como NHibernate, etc
    Si bien es absolutamente cierto que Spring.NET no es una mera portación del Spring de Java (un estándar de facto en dicha plataforma), quedó la sensación de que "programar en Spring .NET" si se parecía mucho al entorno de programación de Spring Java: escasa o nula integración con Visual Studio u otro IDE, con lo cual Spring.NET no se vio tan atractivo frente a otros frameworks como los que provée Patterns and Practices, integrados a Visual Studio en la forma de Sofware Factories, etc. El público reclamó por eso en el momento de las preguntas, y ante la respuesta vacilante y dubitativa de los oradores, hicieron valer cierto descontento en las evaluaciones

    De ahí me fui a la festichola del evento, y a la cucha

    June 06

    [Serie] TechEd 2007- 3ra Jornada

     YAGNI,  You Ain't Gonna Need It (No es algo que vayas a necesitar). El día de hoy estuvo dominado por ese acrónimo que es una recomendación a los que desarrollan, directa o indirectamente, software para que no estén aplicando tecnologías, productos o prácticas sólo porque se convencieron de que es eso o el caos (sea porque leyeron un paper muy convincente, porque los visitó uno de estos evangelizadores de alguna empresa de tecnología, sea porque lo leyeron en el suplemento de tecnología de algún diario de circulación nacional -que, sin desmerecerlos, es como si yo me pusiera a opinar de política, del horóscopo o de espectáculos-, sea porque tienen la sensación de que tarde o temprano toda la industria va a estar aplicando eso)

    YAGNI es "pará la moto". No es que lo que te estén ofreciendo no sirve o sea una chantada, sino que tenés que dimensionar realmente el problema que ese producto o tecnología viene a resolver. Y a posteriori tenés que asegurarte de que vos realmente tenés ese problema y que en tu lista de prioridades de problemas a resolver está por los primeros puestos

     

    Es muy loco pero en la jornada de hoy, este debate apareció en forma recurrente. Vamos a los hechos

    La jornada comenzó con una sesión de Christoph Schittko, arquitecto alemán actualmente trabajando en Microsoft USA (que no es Microsoft Corp sino la subsidiaria de Microsoft que atiende a los clientes del gran país del Norte). Fue una típica sesión de arquitectura en el sentido que abordó una de las actividades más amadas y odiadas a la vez por los arquitectos: tomar decisiones de diseño. En esta ocasión en particular, decisiones para combinar en la dosis justa una serie de tecnologías que Microsoft ha venido lanzando y que, a simple vista, parecen lo mismo. Esto claramente introduce confusión para los arquitectos que no entienden la jugada y a la vez temen que eso los lleve a meter la gamba al elegir incorrectamente

    Las tecnologías en cuestión son el orquestador de procesos Biztalk Server, la API Windows Workflow Foundation y el servidor de espacios colaborativos Sharepoint Server, que también permite definir flujos -y para eso viene con un editor ad hoc-. Parecen iguales, pero no son, y de eso se encargó de aclarar Christoph. Mientras que Biztalk está pensado para orquestaciones formales entre procesos de distinta naturaleza (.NET y no .NET, como puede ser SAP, sistemas legados, mainframes, etc), los que a la vez requieren de monitoreos de actividad -tanto a nivel de negocio como de sistema, y cierta inteligencia de negocios asociada, Workflow Foundation se plantea como una alternativa light, mucho más flexible (o sea, sí, menos rígida) pero a la vez menos pretenciosa (chau monitoreo, conversación heterogénea -excepto que ambas puntas hablen un dialecto neutral como WS-*, algo no siempre disponible-, etc) y a la vez, con Workflow Foundation es posible que tengas que meter algo más de código. Biztalk es pesadito en ejecución, otra cosa a tener en cuenta

    Por último, Sharepoint es cierto que habilita workflows, pero poco que ver con los workflows que comentaba en el párrafo anterior. Estas orquestaciones no son entre procesos sino entre personas, y por lo tanto suelen ser más flexibles (menos formales, menos determinísticas, con dedazos onda "aprobalo, aunque no sea lo usual para estos casos, porque es para el cliente Fulano que viene de parte de Mengano"). Normalmente, aunque no es mandatorio, los workflows humanos suelen girar en torno a documentos y por ende Sharepoint usa documentos como estado de la ejecución de sus instancias de workflows

    Por supuesto, esto no quiere decir que las tres tecnologías se anulen entre sí sino que, incluso en un mismo caso de uso, podrían complementarse (imaginate el caso de un workflow centrado en documentos que es iniciado via Sharepoint pero a la vez dispara actividades de Workflow Foundation que terminan, en una de sus etapas, generando eventos que gatillen un workflow de Biztalk que involucre acceso a procesos de terceros -el CRM de la compañía, el sistema contable, etc-)

     

    La siguiente sesión a cargo de Kerrie Meyler y Cameron Fuller, fue acerca de prácticas y tecnologías para monitoreo de soluciones mediante el flamante System Center Operations Manager 2007. Esto tiene mucho que ver con Modelado de Salud (Health Modeling), un post que vengo debiendo de hace rato y que es la parte de una serie en sistemas de misión crítica que abrí en enero (consistía en tres posts, pero llegué a escribir sólo el primero y vendo arrojando timeout desde entonces). Los muchachos abrieron la sesión explicando la metodología para planear la arquitectura de monitoreo. Aunque nunca te hayas dedicado a estos temas de infraestructura, te anticipo que no dista mucho de los métodos que hayas aplicado para desarrollar: una etapa de assessment (o de evaluación del escenario), un prediseño, una prueba de concepto, un plan de trabajo, un piloto, etc. Y como siempre: el negocio manda. Si no hay una necesidad de negocio detrás -como podría ser, en este caso, tener los sistemas en línea funcionando porque operar el negocio en forma manual impacta negativamente en la productividad (y por lo tanto en el revenue)- difícil que el chancho chifle

    Después comentaron los componentes de System Center Operations Manager 2007, sus agentes de recolección de eventos, sus reportes, su integración con los procesos a monitorear (mediante algo llamado paquetes de administración o management packs), etc. También comentaron topologías de deployment de los servidores. Me pareció completa en cuanto a mentoring. Si no sabías nada de todo esto, creo que te llevaste algo sustancial. Pero el público enterró literalmente a los speakers de feedback negativo. La crítica generalizada fue que la presentación fue súper básica (una hora y cuarto para terminar escuchando cosas que en cualquier folleto de MOM están sobradamente destacadas)

    Algo que deberé tener en cuenta si es que me vuelven a designar al frente del track de Arquitectura el año que viene (si es que sigo acá y no me rajaron antes, huelga decirlo)

     

    Entonces nuevamente se me hizo la hora de pararme al frente del stand del Equipo de Arquitectura, y éstas fueron las inquietudes más destacadas que me plantearon quienes se acercaron:

    • "Dame razones por las cuales habría que adoptar la Enterprise Library" me disparó un arquitecto -debo aclarar que comparto el stand con el comité de Patterns and Practices y la consigna con ellos es cubrirnos mutuamente si es que el otro no está presente. La Enterprise Library es de ellos en realidad
      Cuestión que acá tenemos un ejemplo de YAGNI. La Enterprise Library es un conjunto de frameworks que tienen como propósito proveer funcionalidades no presentes en la versión de la plataforma .NET a la que pertenecen, o eventualmente extender o simplificar algunas de sus APIs (por ejemplo, el Data Access Application Block significa el uso de ADO.NET)
      Hay que usarla o no? era la pregunta. Analicemos juntos tu escenario: tenés que empezar una aplicación desde 0 (cero)? Querés ahorrarte la construcción de piezas que probablemente vayas a necesitar (para caching, manejo de excepciones y/u otras funcionalidades que suelen estar presentes). Si tal es tu caso, esto te puede llegar a servir para evitarte escribir esa lógica vos (y mantenerla posteriormente, claro)
      En cambio, es posible que ya tengas una aplicación construída y también que -o bien te descargaste frameworks para evitarte hacer esta lógica vos, o bien te la terminaste escribiendo, o posiblemente un mix de ambas-. Si te está funcionando lo que hiciste, es más difícil de justificar el decir "migrate a la Enterprise Library". Todavía, aún si lo que hiciste te funciona pero no lo querés mantener a futuro, es posible que te sirva migrar para subirte a este framework que evoluciona a la par de la plataforma .NET (incluso a veces le marca el destino, como pasó con el Updater Application Block que posteriormente fue absorbido por .NET al ofrecer ClickOnce)
      De todas maneras, esto último es relativo: la Enterprise Library no necesariamente conserva la compatibilidad con versiones previas, basandose en la premisa de que trata de sacar el máximo provecho de la versión objetivo de .NET para la que está dirigida, y si eso implica renegar del pasado... arrivederci
      Pero definitivamente, una aplicación .NET que no usa la Enterprise Library es tan válida como todas las aplicaciones .NET que sí la aplican
    • "Hablando del soporte de la Enterprise Library, cuál es su roadmap?" me preguntó otro asistente al evento que había estado escuchando mi speech anterior. El comité de Patterns and Practices es muy organizado en ese sentido, y dispuso en una página cuáles van a ser sus próximas entregas. Respecto de la EntLib, en mayo pasado liberaron la versión 3.1 y no habría, según dicen en esa página, nuevos releases durante el resto del año
    • "Y la EntLib versión 3.0, qué agrega de novedoso respecto de la 2.0?" Lo más destacable, aunque no lo único, el Validator Application Block que (sea mediante configuración, mediante atributos o directamente en código) habilita la agregación de reglas de validación de componentes y sus propiedades; y el Policy Injection Application Block que permite, también mediante configuración o mediante atributos, interceptar llamadas a métodos para ejecutar (a priori y/o a posteriori) código adicional que podría eventualmente cambiar el curso de los acontecimientos

       
      Interceptando invocaciones mediante el Policy Injection Application Block

    • "Y el soporte de la Enterprise Library? Cuál es el compromiso de Microsoft para con la misma?" (Qué buena pregunta, Mario) Es importante leer siempre el Acuerdo de Licencia de Usuario Final (End-User License Agreement o EULA), tanto de la Enterprise Library como de cualquier producto (sea comercial o de uso libre). El de la EntLib, particularmente, está haciendo click acá, y es conciso y al grano. Expresa de movida que si no estás de acuerdo en todo o en parte, que desistas de usarlo y quedamos amigos. Si lo usás, el producto se ofrece tal como es y Microsoft se deslinda de la responsabilidad. Alguna vez comenté esto en Chile y se me vino la audiencia encima diciendo que cómo podía ser, que lo de Microsoft era poco serio, irresponsable, etc. Entonces pregunté quiénes usaban Firefox de browser. Algunos levantaron la mano. Entrá acá (es el acuerdo de uso de Mozilla) y decime qué quiere decir el artículo 6. Después pregunté quiénes ejecutaban aplicaciones Java usando la JVM de Sun (entrá acá y contame, de nuevo, qué te está dando a entender Sun con su artículo 6). Lo mismo para Linux y gran parte del Open Source que goza de una muy buena -y merecida- reputación y sin embargo el buena onda que te lo está ofreciendo gratis -como en este caso Microsoft con su EntLib- no se hace cargo del uso que vayas a darle
    • "Queremos migrar aplicaciones VB6 a .NET: deberíamos ir a Windows Forms o a Windows Presentation Foundation?" Otra vez YAGNI, no? Es tu necesidad de negocio la que te lleva a migrar? Es que el soporte extendido de Microsoft para con VB6 ya terminó? Qué expertise tenés en WinForms respecto de WPF? Si las aplicaciones que estás planeando están pensadas para Windows Vista y apuntando al largo plazo, las acciones de WPF suben. Si sólo estás migrando por mantenerte en una plataforma soportada y te sentís más familiarizado con Windows Forms que con WPF, a la par que el usuario te está pidiendo nuevas funcionalidades de negocio a las que vas a tener que dedicarle tiempo, andá olvidandote de WPF por el momento
    • "Existe algún tipo de certificación de Arquitectura?" Sí: el programa MCA
    • "Tenemos que hacer aplicaciones pensadas para estaciones que eventualmente van a estar un período desconectadas de la red y sin embargo deben seguir operando... alguna idea, herramienta, técnica?" Echar un vistazo al Smart Client Software Factory y al Mobile Client Software Factory, que abordan la problemática de la desconexión ocasional y posterior sincronización de operaciones cuando la conexión se reestablece. También, la Enterprise Library ofrece el Caching Application Block, que te puede almacenar esa info del servidor que vas a necesitar disponible durante la desconexión (códigos de provincia o departamentos, etc). Ayer un cliente me decía "de todas maneras, hay que asegurarse que todo lo que se almacene localmente para forwardear luego esté encriptado: no sea cosa que te roben la notebook y terminen accediendo a info confidencial que vos ni siquiera llegaste a sincronizar y -por consiguiente- vas a tener que dar por perdida". Sabias palabras. Excepto que las Software Factories que te mencioné antes ya se hagan cargo de tal detalle, el Cryptography Application Block puede aplicar bien acá
      No obstante, uno de los clientes me preguntaba "y qué garantiza que, cuando la conexión vuelve, la sincronización se realice efectivamente?" No supe la respuesta dado que no probé efectivamente estas software factories. En el caso de que no provean nada, habrá que implementar mecanismos de notificación de las transacciones realizadas (sea un log de eventos, sea una ventana de operaciones aún pendientes, etc)
    • "Me gustó todo esto que ví de Agilidad, cómo empezar a investigar el tema?" Hará un par de meses respondimos a esa pregunta con esta página. Y llegó en ese mismo momento Peter Provost, nuestro gurú en temas de Desarrollo Ágil, a hacerse cargo de la situación. Peter le hizo unas cuantas preguntas al cliente respecto de su contexto para asegurarse de que fuera que quería aplicar procesos ágiles sólo porque está copado (YAGNI, de nuevo)
    • "Todos estos contenidos son una masa, re interesantes, pero debo admitir que más aprendo, más me complico porque hoy me lleva 3 horas hacer algo que antes me llevaba 1, ya que antes no pensaba tanto las cosas y ejecutaba más rápido". Qué punto, no? Admito que a mí también me ha pasado esto más de una vez hasta que terminé de entender que por muy políticamente correcta que parezca una nueva técnica, producto o tecnología... YAGNI. Mirá si me habré ensartado, eh? Enterprise JavaBeans y otras APIs Java, y lo mismo me tocó con el stack de Microsoft. No quiero decir con esto que nunca haya que innovar, sino que más allá del deber que tenemos de mantenernos siempre informados de los avances en esta ciencia, aplicar todo esto debe estar sujeto a una oportunidad real y concreta (sea de mejorar la productividad o de abaratar costos, mejorar la automatización, o una mezcla de todo eso)
    • "Hemos aplicado SOA en nuestra organización con unos resultados tremendos, tan notables que ahora mi jefe quiere que tres aplicaciones VB6 -que serán obsoletas pero andan que son un reloj suizo las tres- sean incorporadas a la federación de aplicaciones. Yo me resisto porque nos va a costar un Perú y, la verdad, no hay una necesidad real de subirlas a la federación". Si no hay una necesidad concreta, eso no habla muy bien del jefe que está ignorando el principio de YAGNI. Ahora, si el día de mañana esas aplicaciones, esos silos, necesitan compartir funcionalidades (porque consuman o porque provean) con el resto de la federación, no hace falta migrarlas. Basta con agregar una capa de integración usando como superficie de contacto nada más que los servicios que se deben consumir y los que se deben brindar (para lo cual se podría usar el SOAP Toolkit). El resto queda dentro de la frontera de la aplicación y por ende es independiente de la federación. Por consiguiente no debería migrarse, excepto que haya otras razones como ser el poder beneficiarse del código administrado de .NET, etc. No son razones menores, sin duda, pero el tema es "con qué presupuesto cuentan para encarar la migración, qué esfuerzo les va a llevar, qué otros proyectos tienen en carpeta, qué prioridad tiene éste respecto de los otros", etc

     

    Durante la tarde se repitieron dos sesiones: la de Patrones de Diseño de Bases de Datos del lunes (a cargo de Stephen Forte) y la de Juval Löwy de ayer, respecto de aplicar técnicas de orientación a servicios sobre el proceso mismo de desarrollo de aplicaciones SOA

     

    La jornada la cerró un totem de la Ingeniería de Software: el sueco Ivar Jacobson. Jacobson es uno de los papás de UML y también de RUP. Bueno... al respecto dijo "es cierto que yo creé RUP con lo cuál RUP es mi bebé. Es cierto también que luego RUP creció por las suyas, no? Y bien, como sabrán, los niños al crecer necesitan de algunas... correcciones". El público estalló en carcajadas

    Lo cierto es que Jacobson explicó las razones por las que descrée hoy de sus trabajos previos. Y ojo, asumiendo la responsabilidad. Pero a la vez justificándose de que lo que ofrecieron en aquellos años (que hoy es usado ampliamente), fue lo mejor, lo más evolucionado que pudieron ofrecer en ese momento. Pero que hoy, luego de haberlo aplicado y haber visto cómo otros lo aplicaron y extendieron, Jacobson está en condiciones de evolucionar todo esto nuevamente

    No es muy distinto a Microsoft, fijate: qué fue de la vida de COM? Qué de MTS? Y de FoxPro? El DOS? Todo tuvo su momento y su lugar

    Jacobson dice y predice que en el futuro no va a haber más metodologías prescriptivas como lo fueron UP, procesos estilo CMMI o procesos ágiles estilo XP, SCRUM y otros. En cambio, lo que va a haber es una paleta de prácticas. Las prácticas van a venir primero y las metodologías van a ser meras colecciones de prácticas que las organizaciones van a escoger de la paleta

    Si la pensás un poco, Jacobson no sólo puede tener razón en lo que dice que va a pasar en el futuro: de hecho tiene razón en que eso fue lo que ha venido pasando!!! Yo conozco un montón de organizaciones que dicen que aplican UP, o XP o CMMI pero en realidad lo que tienen es una versión personalizada de esas metodologías y procesos. Por ejemplo, son muchísimos los casos de equipos de trabajo que me han tocado conocer que aplican TDD (test-driven development) y dicen "estamos rigiendonos por la metodología eXtreme Programming". Minga! A dónde está el pair programming, a dónde el planning game? Puedo ver las User Stories? Puedo revisar las CRC?

    Es claro que cuando vamos a aplicar una metodología, hacemos lo mejor que podemos con la misma, pero siempre dentro del sentido común. Jacobson no sólo es conciente de esto: también es conciente de que la mayoría de la gente que compró los libros que escribió... no los leyó!! El mismo confesó: "al dejar Rational, la compañía que yo mismo co-fundé y de la que finalmente terminé siendo un empleado, abrí mi consultora Ivar Jacobson Consulting. Para qué? Ya que los que compraban mi libro no lo leían, les ofrecía ahora consultoría para terminar de explicarles qué era lo que el libro decía". De nuevo, carcajadas y aplausos en toda la sala

    Jacobson explicó entonces que en los últimos años creó un nuevo proceso llamado EssUP (por Essential UP, detalles en su portal http://www.ivarjacobson.com) pero no es un rebranding de UP ni de RUP. Es de veras un proceso basado en ocho prácticas que él mismo te propone "andá adoptándolas de a una: nunca las adoptes sólo porque yo te dije que había que hacerlo". YAGNI otra vez!!

    Y el viejo nos sorprendió a todos: abrió Visual Studio Team System y nos mostró cómo lo extendió para que sea tu herramienta EssUP. Y era tal cual! Visual Studio te permitía crear tu proceso basado en EssUP como vos quieras. Esto es, podías ya tomar alguna de las ocho prácticas, podías editarlas y modificarlas para adaptarlas a tu contexto, podías agregar prácticas meramente tuyas... lo que quieras

    Jacobson nos contó que si programás en Eclipse, tiene hecho también el plugin para dicho IDE. Las ocho prácticas de las que te comenté se basan en lo mejor de RUP, lo mejor de CMMI y lo mejor de los procesos ágiles

    Cuando terminó fueron (fuimos) varios los que nos acercamos para sacarnos una foto al lado de él. Más tarde fue a revisar las evaluaciones a los oradores en lo que va del TechEd. Jacobson viene liderando cómodo, seguido por Juval Löwy, David Chappell y Rocky Lhotka

     

    Vamos a ver qué pasa mañana cuando Rod Johnson salga a la cancha

    A propósito de mañana, es posible que no postée la jornada dado que tenemos la partuza del TechEd y creo que vuelvo tarde. En tal caso nos reencontremos el viernes

    June 05

    [Serie] TechEd 2007- 2da Jornada

     Jornada  de luxe la de hoy, como pocas, combinando no sólo personalidades sino también haciendo un juego variado entre contenidos de Infraestructura y de Desarrollo. Como habrás notado, en la columna derecha del blog puse el keynote de Bob Muglia de ayer, que ya está publicado. Lo voy a dejar ahí hasta el miércoles de la semana que viene

    Algo que está funcionando muy bien, ya que me garcaron y me dieron nada más que 20 (veinte) slots, es que eso ha permitido que no haya sesiones de arquitectura que se solapen. Vamos YA a los hechos

    • Rushabh Mehta dio el puntapié inicial a primera hora de la mañana, con una sesión sobre Consideraciones de Diseño para ETL (Extracción, Transformación y Carga de datos para el armado de Warehouses de información utilizables en Inteligencia de Negocios -Business Intelligence o BI-). Comenzó revisando los problemas frecuentes que se presentan cuando tenemos varias fuentes de datos, quizás algunas de ellas no confiables (ojo al piojo: en el momento de la carga vos no sabés que tenían info fasula; te vas a apiolar más adelante cuando llegues a conclusiones que no se las crée ni el ratón Miguelito) y por ende te llevan a meter la gamba. El speaker parece que del tema conocía, porque complicó más la cosa planteando escenarios donde tenés más de un proceso de carga. Es más, tenés un workflow de procesos de carga con lo que, si algo entra mal, andá a darte cuenta después de la transformación
      El amigo después delineó las etapas de una carga de datos efectiva, que contemple puntos de control a los que podamos ser capaces de volver en forma retroactiva. Me gustó realmente el orador porque presentaba alternativas para todo, sujetas -claro- a condiciones. Cómo y cuándo encarar rollback automático, cómo y cuándo no va a quedar otra que hacerlo artesanalmente (seh: a manopla)
    • Después pasó al frente uno de los platos fuertes que trajimos a este evento: Juval Löwy. La propuesta que nos planteó ahora que te lo cuente vas a pensar que debe haber salido de joda anoche y se le habrá ido la mano con el chupi. Pero creéme que tenía un dejo de coherencia. Juval comenzó planteando realidades que se presentan en los proyectos basados en Arquitecturas Orientadas a Servicios, destacando los riesgos que este tipo de proyectos presenta (justificando los mismos en que la aplicación se basa en servicios distribuidos). Entonces reveló su receta para que este tipo de proyectos llegue a buen puerto. Para ello abordó primero la problemática del armado del equipo de proyecto, cuántos arquitectos y de qué perfiles según el tamaño del mismo; también cómo repartir los servicios entre los desarrolladores que van a tener que construirlos; cómo ir integrando luego las piezas a medida que son completadas; cómo testear los servicios y cómo estimar el costo del proyecto basado en los servicios que hay que construir
      Juval terminó con una discusión interesantísima respecto de la conducta que puedan presentar tanto el esfuerzo del equipo (o sea, el trabajo invertido, las horas/hombre en otras palabras) como el progreso del proyecto (el porcentaje completado) respecto del plan inicial
      Simplemente mirá esta presentación cuando esté disponible (me voy a encargar de anunciar tanto en el blog como en el portal de arquitectura cuando las sesiones del TechEd estén liztaylor)

    Al finalizar esas dos sesiones empezaba mi turno al frente de la estación para demos en el stand del Equipo de Arquitectura. Las dudas que los que se me acercaron me han planteado fueron, a grandes rasgos, tres:

    • Cómo entender de Arquitectura aunque uno no vaya a jugar el rol de Arquitecto. El que me hacía la pregunta era el CTO (Chief Technology Officer) de una compañía dedicada a la Salud que necesitaba entender el idioma de los arquitectos que lo asesoraban. En otras palabras, quería saber cómo manejar los conceptos, cómo saber por dónde pasa la cosa, de qué se está discutiendo hoy
      Me dio pie a mostrar el portal y explicar cómo está organizada la información en el mismo, recorriendo en un pantallazo los pilares de una arquitectura distribuida, y también tópicos especiales que están en la agenda tecnológica de hoy. También, los sitios que creamos para verticales industriales y las formas de estar sintonizado con el contenido (las suscripciones RSS) y especialmente algo que te va a venir al pelo: el mapa del contenido


      Hacé click en esta imagen para probarlo Esta aplicación requiere la extensión de Internet Explorer que te habilita a ejecutar applets Windows Presentation Foundation (WPF) embebido (extensión xbap, no estoy muy seguro y no quiero hablar al cohete pero me parece que si no la tenés instalada te va a promptear para ver si aceptás descargarla). Concretamente este mapa te ofrece tres vistas de la información: por tópicos (llamalo SOA, Experiencia de Usuario, Software as a Service, Software Factories, etc), por autores que hayan contribuido a un dado tópico o por contenido de un tópico (esto es, los artículos, webcasts, etc). Al pasar por encima de un nodo, te ofrece un menú contextual que ofrece cosas relacionadas con ese nodo (por ejemplo, lanzar el artículo o video, o bien ver que otros artículos escribieron sus autores, etc)
      Es una forma novedosa de encontrar información fuertemente relacionada, que el portal no te puede ofrecer ya que la info está clasificada desde lo más nuevo a lo más antiguo (es decir, el orden viene prefijado de antemano). Los créditos a Simon Guest
      Echale un vistazo porque creo que te vas a familiarizar rápido ya que esa aplicación usa directamente la base de conocimiento por la que clasificamos el contenido, y tiene categorías que aún no llegaron a tener página propia en el portal (como pueden ser Web 2.0, Misión Crítica, Transacciones y varias otras)

    • Otra de las consultas que me hicieron fue referida a información sobre Software Factories. No lo que en América Latina entendemos por, sino lo que Microsoft definió con ese nombre: herramientas alrededor de un lenguaje específico de dominio -o sea, no genéricos como C# o Java- que permitirían esconder todo contacto con APIs, restingiendo toda la gramática a elementos de un dominio de alto nivel. Por ejemplo, imaginate un lenguaje especifico para odontólogos que te permita -entre otras cosas- revisar radiografías digitalizadas de la boca de un paciente, a través de un lenguaje con primitivas tales como

          SELECCIONAR PACIENTE GONZALEZ
          MOSTRAR SEGUNDO MOLAR INFERIOR IZQUIERDO
          ROTAR 90 GRADOS SENTIDO HORARIO

      y que todo eso después se compile a componentes C# que a través de Windows Communication Foundation y DirectX terminen de cocinar el estofado
      Claro: sin Software Factories podríamos haber logrado lo mismo encapsulando la complejidad de WCF, DirectX y la API que fuera mediante el desarrollo de componentes, de modo de lograr algo como

          Paciente paciente = PacienteDAO.Seleccionar(Gonzalez);
          UIAgent.Show(paciente.GetDiente(Diente.SEGUNDO_MOLAR_INFERIOR_IZQUIERDO);
          UIAgent.Rotate(90, CLOCKWISE);

      Es decir, en lugar de introducir la complejidad de un nuevo lenguaje, introduzco la complejidad de una nueva API. De hecho, esta última solución parece mejor porque sigo teniendo el resto del framework .NET disponible (en verdad, incluso WCF y DirectX si se me canta usarlo de todas formas). En cambio, con el lenguaje específico de dominio me perdería la mayoría de las cosas que poséen los lenguajes .NET como podrían ser las caracterísitcas de la orientación a objetos, acceso a -justamente- todas esas APIs que quedaron encapsuladas
      Sin embargo, justamente eso es lo que se pretendía: crear un lenguaje que realmente limite by design el uso que se hace de la plataforma .NET, que lo aleje definitivamente del alcance de los programadores de lógica de dominio
      Esto sugiere un modelo de trabajo similar a una línea de montaje de una manufacturera: los operarios son especialistas en determinada parte del proceso de construcción, pero el trabajo conjunto y secuencial de todos acaba logrando los productos terminados. De ahí la denominación de Fábricas de Software
      Para conocer más en detalle de este punto, el portal ofrece unas páginas especificamente dedicadas a este tópico, así como también el año pasado salió un número del Architecture Journal enfocado en Software Factories
    • La última pregunta significativa que me tocó responder fue acerca de guías para versionar, desplegar y monitorear servicios, lo que me permitió referenciar al trabajo que Mark Baciak está realizando con un proyecto cuyo code name es Alchemy, y que trata de una infraestructura que soporte aplicaciones orientadas a servicios, el ciclo de vida de estos últimos (su control de cambios), y que a la vez permita automatizar su administración y monitoreo a fin de prevenir el incumplimiento de los parámetros de nivel de servicio acordados

    En el durante me crucé me vinieron a visitar ciertas personalidades, que nombro por orden de aparición: Leandro Olivestro (Q4Tech, un experto en aplicaciones móviles que nos ha permitido generar varios casos de uso en Sudamérica), Daniel Cazzulino (Clarius Consulting, otro grosso que lleva escrito varios libros sobre desarrollo web para Wrox y Apress, además colaboró con la flamante versión 3.0 de la Enterprise Library), Neil Roodyn (un gurú de procesos de desarrollo ágil), Arvindra Sehmi (director de arquitectura de software de Microsoft Europa), David Platt (te había comentado sobre él ayer)  y otros

    En el interín y al terminar mi participación en el stand del Equipo de Arquitectura, hubo más sesiones del track que vale la pena comentar:

    • David Chappell abordó el stack de productos de Microsoft para Manejo de Identidades. Tras una breve introducción al tema y a sus conceptos básicos (qué es una identidad, qué un token, etc), comentó las estrategias disponibles para verificar identidades tanto dentro de dominios específicos como a través de internet destacando las facilidades ofrecidas por Active Directory, Windows Cardspace, AD Federated Services, Identity Lifecycle Manager, etc. Finalmente dedicó unos minutos a mecanismos de autorización basados en AzMan
      No sólo viene siendo, hasta ahora, nuestra presentación mejor rankeada sino que de todo el evento, considerando otros tracks que el de Arquitectura, está entre las 10 presentaciones mejor evaluadas
    • Rockford Lhotka hizo un balance de las técnicas que desde hace unas décadas han venido dominando la escena (Orientación a Objetos, Arquitecturas Cliente/Servidor, Arquitecturas en Capas, Orientación a Servicios, Workflows) y aunque apeló a ironías al justificar que estas técnicas surgen porque tanto Microsoft como su competencia necesitan seguir vendiendo, después aclaró que se trataba de una broma y que la realidad es que las Ciencias de la Computación van resolviendo problemas en base a las necesidades de la industria, y en la medida que esos problemas aún dejan cabos sueltos, nuevas técnicas llegan atrás para cubrirlos
      Lhotka mostró ejemplos de arquitecturas que combinaban lo mejor de cada técnica, demostrando así que las mismas complementan sus enfoques, no los contrastan ni contraponen
      La sesión fue súper bien recibida por el público que dejó su marca en los comentarios
    • Y finalmente, cerrando la jornada, Caroll Moon, arquitecto del Centro de Excelencia en Operaciones de TI, brindó un pantallazo acerca de MOF, Microsoft Operations Frameworl, una metodología para Control de Cambios, Operaciones y Monitoreo de aplicaciones que permite lograr alta disponibilidad de los sistemas de misión crítica. Explicó la relación de MOF con ITIL, el rol de Microsoft en el comité que mantiene ITIL, las certificaciones disponibles, las herramientas del stack de System Center que sirven para planificación de la capacidad (capacity planning), el monitoreo, las alarmas, escalaciones, así como también las best practices de todo eso
      Comentó un caso de estudio interno, basado en Exchange Server con una base de 100 mil usuarios. Gracias a MOF, el uptime (tiempo en que el servicio Exchange está disponible), es superior al 99.99% anual

    Estimados, esto fue todo por hoy

    June 04

    [Serie] TechEd 2007- 1ra Jornada

     Bob Muglia,  vicepresidente de Servidores y Herramientas de Microsoft, abrió el evento con un clip que grabó junto al Dr. Emmett Brown (el científico de Volver al Futuro caracterizado por Christopher Lloyd)

    En el mismo, el profesor lo hacía volver a los años 2001 y 2003 para que revise los mensajes que Microsoft había estado anticipando en aquellos años y así se inspire para contar hoy los resultados y plantear "cómo sigue"

    Como era de esperarse, una vez que "vuelven al futuro" (o sea, a ahora), entran al recinto en el clásico De Lorean de la saga (que, como era de la década del 80, tenía una diskettera por donde se cargaba el software que permitía viajar en el tiempo)

    Muglia realizó un pantallazo del presente y futuro de la plataforma, tanto para desarrolladores como para IT Pros. No faltaron, por supuesto, demos de todo. Se vieron videos en Silverlight (el plug in cross browser que se plantea como competidor de Adobe Flash), novedades administrativas de SQL Server 2008, System Center Operations Manager 2007, Windows Server 2008, Biztalk Server 2006 R2, Windows Live, Office Business Applications y, como era de esperar, Visual Studio 2008. A decir verdad, y esto creo es el mensaje más importante, señores, hay .NET para rato. .NET es y seguirá siendo la forma de extender la plataforma básica de Microsoft (no hablo del sistema operativo solamente sino también extender documentos Office, portales Sharepoint, flujos de Biztalk, etc)

    Nota: el keynote de Muglia está disponible para ver on demand haciendo click acá
    Dura 90 minutos incluyendo la payasada de Volver al Futuro 
     

    Todos estos avances que la plataforma viene realizando (me he referido sólo a la versión 3.0 en Marzo pasado, pero se vienen varios nuevos!!) no son meros esfuerzos aislados sino que siguen una trama argumental que va siendo definida por la plataforma completa

    Pero todavía más importante que lo anterior es el hecho de que, si tenés que meter código, éste va a ser muy poco!! La plataforma de por sí está demasiado integrada. Quiero decir, es muy sencillo agregar valor con sólo juntar pocos componentes (una base de datos SQL con Sharepoint, o con Excel Services, eso luego adjuntarlo en forma automática a un correo electrónico, etc). No te voy a exagerar diciendo "no metés ni una línea de código". Te digo la justa, simplemente: es poco lo que tenés que codificar para puentear info entre dos aplicaciones

    Obvio, uno me puede decir "y pero yo si no programo me aburro". Creéme que no vas a tener tiempo de aburrirte cuando veas que la facilidad con la que vas a obtener resultados que antes ni te hubieras planteado de sólo imaginarte lo que ibas a tener que codificar. Esto es algo que a mí, justamente, me viene pasando mucho ultimamente: veo los avances de la plataforma de Microsoft y se me abre mucho el bocho de cosas que podría hacer (digo, que de haber estado disponibles años atrás seguramente hubiera hecho). Ese es el punto. Empezás a encadenar cosas para agregar valor de la sola unión de las partes y ya no querés parar

    Para un reporte ampliado del keynote de Muglia, te recomiendo éste que publicó .NET Development el mismo día: click acá

     

    Bueno, volviendo a la expo, después que terminó el keynote me tocó cumplir con una de mis responsabilidades principales de este evento: mostrarles a los attendees (asistentes a la conferencia) en una estación para demos las cosas que estamos haciendo en el team, y a la vez -claro-, escuchar sus inquietudes para ver si lo que hacemos realmente es relevante o estamos en otra página que el field

    Haciendo un resumen de lo que lo más interesante -o al menos, que más me llamó la atención a mí-, las inquietudes principales pasan mucho por ver cómo enlazar la Infraestructura con el portfolio de soluciones (hechas en casa o de terceros)

    Esto me dio pie para mostrarles, en nuestro portal MSDN Architecture, como hemos venido ultimamente agregando información de Technet (IT Pros) a la par que el contenido puramente para desarrolladores. Porque yo tengo tan claro como el que más, vengo del field, quiero decir, no nací ayer: en las organizaciones no es que cualquiera haga cualquier cosa pero sí es claro que eso de "yo soy desarrollador y vos sos IT Pro" no es tan tajante

    A mí me tocó ser jefe de proyecto, por decir, Java y terminar instalando el korn shell de Linux porque algún instalador de Red Hat lo requería. Y cuando terminaba tenía que seguir programando en Java, siendo que era el jefe del proyecto (claro, no full time pero más de una vez hacía yo las pruebas de concepto -todo o parte- para decidir si seguir adelante con un dado framework o buscar otro o darle a mano nosotros)

    Justamente por eso es que me dí el gusto de poder mostrar que todo aquello relevante para arquitectos (sean de infraestructura o de soluciones) se está incluyendo en el portal. En lo que va del año hemos venido incorporado 840 nuevas piezas que ya están disponibles y accesibles desde las distintas páginas del portal. De las mismas un 60% no tiene ni un mes de antigüedad cuando empieza a estar disponible (a decir verdad, vas a notar que el feed RSS publica las cosas más relevantes que Microsoft liberó la semana anterior)

    He recibido -y quiero agradecer por ello- varias felicitaciones por la arquitectura de la información del portal (es decir, la forma en que la navegación está organizada). Pero eso, claro está, de la gente que sabe del portal y lo usa. En cambio como punto en contra debo decir que no fueron pocos los arquitectos de plataforma Microsoft que desconocían de su existencia. Evidentemente tenemos que marketinear mejor esto

     

    En cuanto a personalidades, he conocido por fin en persona a Dave Platt (el del post de Abril sobre su libro "Por qué el Software Apesta") -le mostré el dichoso post y me pidió que le traduzca el comentario de Matías Iácono: se copó y me dijo que le gustaría viajar a Argentina y presentar el libro allá, aunque por ahora anda con la agenda completa-

     

    Vamos a las sesiones del track:

    • Ron Jacobs pasó revista a los ejes por donde se ha venido debatiendo estos últimos años la Arquitectura de Software; lo que funciona y lo que no; cómo el clásico patrón de arquitectura Modelo-Vista-Controlador ha evolucionado en el actual Modelo-Vista-Presentador (con los por qués del cambio); las verdades sobre el desarrollo ágil y las prácticas que han venido funcionando; las conductas que conviene evitar (como YAGNI o "You aren't going to need it", en referencia a pararle la mano a los carlitos que quieren meter funcionalidades y otros chirimbolos por si acaso, comiendose innecesariamente horas del proyecto en algo superfluo); y las conductas que sí vale la pena adoptar (las clásicas, no? Test-Driven Development, Mocking, etc)
    • Después de comer, Brian Noyes (IDesign), presentó una sesión acerca de ClickOnce para arquitectos. Es decir, capacidades que ClickOnce posée que quizás no son tan de dominio público y no se aprovechan al tener que hacer roll out en las workstations de las nuevas versiones de las aplicaciones. Brian es de los arquitectos que escriben código y se la bancan, así que hizo demos de todo. Incluyó aspectos de seguridad para que ningún piola se haga pasar por la entidad que generó los binaries y nos meta caballos de troya en versiones alteradas de la aplicación, etc
      También anticipó las novedades de ClickOnce en Visual Studio 2008, como por ejemplo el soporte a Firefox. Destacó las similitudes y diferencias de distribución de aplicaciones Windows Forms y Windows Presentation Foundation, etc
      Para quien tenga interés, Brian escribió un libro sobre todo esto (detalles acá). Sala llena y un público que participó muchísimo
    • Tom Fuller (consultor senior de SOA) se mandó una presentación impresionante, muy madura, de los sí y los no de construir servicios. Arrancó por blanquear que el mensaje de reusabilidad con el que la bandera de SOA ha venido siendo agitada es un poco irreal dado que se dice de antemano y sin considerar el contexto que las organizaciones tienen. Con esta premisa, entonces, siguió adelante explicando formas de mitigar los problemas frecuentes que complican la reusabilidad de servicios. Y no se quedó en eso: cubrió también modelado de contratos (entre consumidor y proveedor de un servicio); explicó por qué WS-* aunque sea complejo es importante y no reemplazable por POX (el XML llano de la vieja guardia); manejo de excepciones adecuado, según que la pelota deba picar en el proveedor o el consumidor del servicio (concepto que debería ser reusado para manejo de excepciones en general, aunque no sean distribuidas); correlación de mensajes; autonomía de servicios; granularidad; procesado masivo (para evitar una conversación charlatana -chatty- entre las partes) y el consiguiente manejo de las unidades de trabajo; también un tema fundamental como lo es la arquitectura de servicios (es decir, su agrupación en módulos, agregación de servicios de menor nivel, etc); tolerancia a fallos... Ufff...
      Imperdible!!! Bueno, tanto ésta como todas las presentaciones del track de Arquitectura van a publicarse pronto
    • Finalmente Stephen Forte nos dedicó una sesión de diseño de bases de datos, pensando en escalabilidad y mantenibilidad de los mismos. Atención: no hablo de patrones de diseño para acceso a datos. Eran patrones de diseño, sí, pero para diseñar aquellas tablas altamente transaccionales, también para aquellas dimensiones que cambian lentamente, y por último patrones de diseño para warehouses. También se la jugó y presentó un par de patrones más para alta disponibilidad de la información y para escalabilidad mediante el particionado horizontal (o sea, agrupar las filas de una tabla lógica en varias tablas físicas o particiones) y vertical (o, en otras palabras, dividir la info según columnas cohesivas que dependen de la misma clave principal)
      A pesar de haber presentado en último lugar y siendo que el primer día todos arrastran un poco de jet lag... la gente prendida a full y Stephen fue el orador mejor evaluado hasta ahora

    Estimados, hablando de jet lag me voy a apoliyar y esto sigue mañana. Por supuesto que estos posts van a ir siendo reeditados para enprolijarlos, agregar más links a la data, alguna que otra foto, etc

    Como decía Victor Sueiro, esto recién empieza