Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.
Somos una empresa ubicada en el pais vasco y nos dedicamos a la producción de sistemas de gestión vía WEB.
Descripción de la plaza.
Buscamos un programador de flex para desarrollar RIAs. En concreto la parte de la interfaz gráfica como diseño de pantallas, paginación, gestión de usuarios, usabiliad, etc., sin entrar en la lógica de negocio de nuestra aplicación que sería responsabilidad nuestra.
En concreto, se trata de labores de apoyo y soporte, por proyecto, a nuestro equipo de desarrollo. Pretendemos buscar un colaborador para los picos de producción y así externalizar desarrollos. Dichas colaboraciones se traducirían a trabajos remunerados durante 2-3 semanas.
Requisitos y conocimiento
El perfil de programador que buscamos se acerca al concepto de freelance (autónomo) con agilidad y disponibilidad para poder responder en plazos cortos de tiempo.
Los conocimientos necesarios para la realización de dichos desarrollos son: arquitectura web, flex, blazeds, java, jboss e hibernate.
Tipo de contrato
Facturas por prestación de servicios bajo presupuesto.
Lugar de trabajo y modo de trabajo.
El lugar de trabajo será el natural del programador. Las comunicaciones se harán vía skype, tfno, email y si fuera necesario, algún desplazamiento.
Finalizo con éste la serie de artículos sobre el último miniproyecto en el que me embarqué hace ahora un mes, Valenbisi para dispositivos móviles.
Tras un par de semanas con las aplicaciones para los principales sistemas operativos para smartphones a pleno rendimiento (excepto iOS), parece que hay mucha más gente con buenos cacharros de lo que yo esperaba, teniendo en cuenta además que es una aplicación enfocada a una zona geográfica muy concreta.
Os comento además que, aprovechando la infraestructura que ya tenia montada y viendo que el proveedor del servicio es el mismo, decidí replicar el sistema para las bicis urbanas de Sevilla, información del estado de las estaciones de Sevici, acompañado también de su aplicación para Android.
Aquí van las estadísticas de descarga de las aplicaciones desde Android Market:
No está nada mal, sobre todo teniendo en cuenta que la de Sevici no la anuncié en ningún sitio . Los números de la de Valencia me parecen espectaculares, desde luego ya hay mucha gente por ahí con un Android.
Y aquí las estadísticas para la aplicación para Symbian desde Ovi Store:
Éstas son, sin duda, más complicadas, parece que en la India se usa mucho Symbian . Aún así se nota que hay descargas.
Finalmente nos queda Blackberry. Tengo aplicaciones para OS4 y OS5, pero esta vez sin presencia en App World ya que me solicitaban firmas de notario, así que directamente pasé de ellos , la distribuyo directamente desde Valenbisi.mobi y que se la descargue quien quiera. De hecho, cada vez que entras, si tu terminal es compatible con alguna de las aplicaciones disponibles, te ofrece la posibilidad de descargar la aplicación. Se han hecho aproximadamente unas 20 descargas de la aplicación para BlackBerry, teniendo en cuenta que la visibilidad así es mucho menor que desde la tienda de aplicaciones, me parece un buen número .
Finalmente tenemos las estadísticas globales de visitas al sitio web, contando tanto los que entran desde aplicaciones como los que entran directamente.
Me parecen muy buenos datos para una aplicación completamente local. Llama la atención el pico de visitas del 8 de diciembre, pero tiene sentido ya que, además de día festivo, hizo un día espectacular con 23º de temperatura, importante para ir en bici . Seguro que a medida que vaya mejorando el tiempo se notará el incremento de uso. Pese a que sólo oímos hablar de iPhone’s y Android’s, fijaos en la sorprendente relación de sistemas más utilizados. Aunque Android pega fuerte, Nokia sigue siendo lo más utilizado, un dato importante a tener en cuenta en cualquier aplicación para móviles que desarrollemos.
Con esto abandono el desarrollo . La aplicación está terminada, funciona bien y parece ser por los comentarios que es fiable. Espero no tener que hacer mucho mantenimiento , me aburre bastante .
Según pruebas realizadas, Flash Player 10.2 es 10 veces mejor, en cuanto a rendimiento de CPU, que su predecesor. Con el nuevo modo de optimización de video llamado Stage Video, se consiguen mejoras substanciales en cuanto a performance.
En el siguiente link encontrareis un post donde lo explica.
Google como siempre haciendo de las suyas esta vez nos presenta Google Body Browser, una aplicación hecha con WebGL que permite explorar el cuerpo humano, como si estaríamos explorando una mapa con Google Earth.
No se necesita ningún plugin para verlo, pero si es necesario un navegador que soporte WebGL (Chrome 9 Dev o Firefox 4 Beta).
Si usas Chrome 8 puedes activar WebGL escribiendo en la barra de direcciones about:flags, después click a “Habilitar” en WebGL y después click en el botón reiniciar.
Procrastinando un poco me enteré que el artista francés Alexandre Oudin, cambió su perfil de Facebook de una manera curiosa:
Confieso que también quise hacerlo, pero me tuve un poco de flojera. Si tú estás interesado puedes usar una plantilla PSD creada por Digital Inspiration. La plantilla muestra paso a paso como personalizar tu perfil.
Confieso que en ocasiones soy de los que usa el buscador de youtube y a veces encuentro mashups(o remixes) musicaleso nomuuuuycuriosos . Aunque con lo simplón que soy me encanta que me pasen remixes chorras, como este doblaje de Epi y Blas “Se pone fino” con el que me parto siempre
Y todos estos remixes/mashups seguramente violen derechos de autor y sean ilegales. Pues eso, interesante documental que trata este tema y muy recomendable vérselo.
Muy buena presentación y reflexión hecha por Conrad Wolfram, sobre como las matemáticas que nos enseñan en la escuela a veces no son del interés de todos los alumnos, y como esto podría solucionarse usando computadoras para quitar la parte aburrida de las matemáticas:
Wolfram sugiere que podríamos quitar la parte aburrida de las matemáticas, sin quitar lo que es la parte intelectual.
Si esto se aplicará ahora, estoy seguro de que nuestros hijos serían unos grandes científicos y mejores matemáticos de lo que somos nosotros.
Las versiones 1 y 2 de ASP.NET MVC permitían el paso de datos desde el Controlador a la Vista a través del diccionario ViewData, de la siguiente forma:
Y ya desde la vista, podíamos recuperar el valor así:
ASP.NET MVC 3 sigue manteniendo este comportamiento, pero ha añadido un mecanismo adicional para facilitar esta tarea: el ViewBag. Se trata de un objeto dinámico disponible tanto en los controladores como en las vistas, sobre el que podemos ir definiendo propiedades sin necesidad de que éstas estén definidas previamente:
Y desde la vista podríamos acceder a ellas de forma directa:
A la vista de los ejemplos, podría parecer que ViewBag y ViewData son dos “sacos” diferentes para pasar información desde la capa Controlador a la capa Vista. Sin embargo, aunque bajo distintas denominaciones, están en realidad accediendo al mismo conjunto de datos. Por ejemplo, el siguiente código resultaría equivalente al anterior:
Probablemente os preguntaréis qué aporta el nuevo ViewBag sobre el tradicional ViewData. Desde mi punto de vista son varias:
en primer lugar, permite un código más compacto y rápido de escribir,
elimina las temidas magic strings propias del diccionario ViewData,
como consecuencia, podríamos beneficiarnos (aunque de momento no he visto que sea así) de refactorizaciones o intellisense sobre estos miembros,
facilita el cambio de tipos. Los elementos de ViewData son siempre de tipo object, por lo que a veces debemos hacerles un cast para poder operar con ellos; las propiedades dinámicas del ViewBag se crean con el tipo apropiado, facilitanto así su manipulación posterior:
En definitiva, una nueva característica que ya podemos utilizar en las versiones preliminares de MVC 3 (aunque hasta la RC2 bajo otra denominación, “ViewModel” en Controladores y “View” en vistas).
Personalmente no me aporta demasiado, pues sigo prefiriendo el uso de vistas con tipado fuerte, pero bueno, está bien saber que existe por si nos puede ser útil en algún momento.
En esta edición, hay por el momento 5 juegos independientes, con las mismas condiciones de la edición anterior:
Multiplataforma – hay versiones para Mac OS, GNU/Linux y Windows
Sin DRM – Los juegos no contienen DRM por lo que podemos instalarlos en cuantas computadoras y sistemas queramos.
Eliges el precio – Cada persona elige el precio que quiere pagar por los 5 juegos.
Donaciones a caridad – Podemos donar parte o todo el dinero a una caridad (EEF y Child’s Play).
Juegos Humble Indie Bundle
Los títulos son Braid, Cortex Command, Machinarium, Osmos y Revenge of the Titans. Como novedad, Braid y Cortex Command hacen su debut en GNU/Linux en el paquete, así como Revenge of the Titans es lanzado por primera vez a través de Humble Indie Bundle. Jugué algunos demos de Puppy Games (responsables de Revenge of Titans), y están muy buenos.
Además de los 5 juegos, tenemos acceso a dos bandas sonoras y un mini-album de Machinarium, Osmos y Revenge of the Titans.
Algunas estadísticas al momento de escribir este post:
Se viene repitiendo una tendencia de la versión anterior: Los usuarios GNU/Linux son los que más pagan. Nada asegura que se repita el hecho de la liberación del código, pero ya veremos…
Quedan prácticamente 7 días de promoción, así que aprovechen para ir y conseguir sus juegos. Les dejo con un video promocional del paquete:
Una vez que tenemos instalado un entorno de integración contínua para PHP, incluyendo un subversión, un hudson y jira, por ejemplo, es probable que todavía no sepamos muy bien qué podemos hacer con él (y una vez que sepamos qué PODEMOS hacer, podremos pensar en qué QUEREMOS hacer). Sobre esto tendría que escribir una tonelada de artículos (y, probablemente, acabe haciéndolo… ). Pero vamos a centrarnos ahora en cuál es el papel de Phing en un entorno de integración contínua.
Para el que no lo sepa, phing es un port de Ant para PHP. Tanto Phing en PHP como Ant en Java, permiten definir un archivo XML con una serie de tareas que se ejecutarán (targets) para, por ejemplo, ejecutar comandos svn, creación-destrucción-cambio de directorios y archivos, permisos, o ejecución de las pruebas unitarias, y un largo etc.
¿Pero eso no se puede hacer con un simple script de terminal? Efectivamente. Phing lo que promete es que al hacerlo definiendo un XML que te permitirá mantener un script de manera más sencilla e incluso reutilizarlo (parametrizándolo) entre diferentes proyectos, etc.
¿Pero eso de los XML´s no es “muy Java” y Ruby no nos ha enseñado que son mejores los DSL´s internos que los DSL´s externos? Efectivamente, mucho mejor sería que Phing se hubiera fijado en Rake que en Ant o Maven y las rutinas Phing se escribieran directamente en PHP y no en un XML….
¿Por qué usar Phing y no directamente Ant? Ant está más extendido y se integra mejor con cosas como Hudson. Pero con Ant, si quieres crear tus propias tareas, tendrás que programarlas en Java. Si extiendes las tareas de Phing creando las tuyas propias, lo harás en PHP… Con Phing, además, te aseguras tener tareas para phpunit, phpcs, etc…
Le he dado muchas vueltas a cómo explicar qué papel juega Phing en todo esto, y creo que lo mejor es ver directamente el esqueleto de una rutina Phing:
Ésta rutina se guardará en un archivo llamado build.xml, preferiblemente en la raiz de nuestro proyecto.
Si, simplemente, escribimos “phing” en la la raiz de nuestro proyecto, obtendremos la siguiente respuesta:
Este pequeño menú se muestar porque hemos hecho que nuestro target “default” simplemente nos muestro las opciones que tenemos. Si ejecutamos:
“phing construct”: phing creará las carpetas que necesitemos para nuestro proyecto, cambiará permisos, creará links, etc… Usaremos esta tarea cuando nos traigamos el código a nuestro ordenador de desarrollo (tras un svn checkout, por ejemplo), o al traernos el código en testing y antes de ejecutar unos test de integración.
“phing metrics”: es un target que lo único que hace es agrupar los targets “clean”, “phpdoc”, “phpunit”, etc… Podremos usarlos por separado. Por ejemplo, si queremos simplemente ejecutar nuestro test unitarios, haremos “phing phpunit” y si queremos generar nuestra documentación haremos “phing phpdoc”. Esta tarea la utilizaremos en desarrollo cuando queramos, pero sobre todo la utilizará Hudson para generar sus métricas para el PMD, el CheckStyle, etc….
“phing testing” y “phing production”. Ejecuta los comandos necesarios para poner en producción (o en testing) un tag de subversion. Quizá ejecutando unos comandos rsync, etc…
Nota: En un entorno ágil ideal, la puesta en producción debería ser tan fácil como ejecutar un solo comando. Por desgracia esto es muy difícil, y aunque es mi objectivo llegar a conseguirlo, no voy a ocultar que algunas de mis puestas en producción distan bastante de ser tan fáciles como escribir “phing production” y punto…
No entro aquí a detallar lo que debería ponerse en cada target. Primero porque mi solución puede no valer para cualquier proyecto y segundo por no extenderme infinitamente. Prometo seguir ahondando en el tema en futuros artículos…
Estos son los enlaces publicados en Variable not found en Facebook y Twitter desde el lunes, 22 de noviembre de 2010 hasta el lunes, 13 de diciembre de 2010.
Lo dicho, que el sábado hicimos el Code Retreat en Zaragoza. Nos juntamos programadores llegados desde Barcelona, Valladolid, Madrid, Valencia y Pamplona aparte de los del cachirulo valley
Nunca había asistido a un evento de este tipo, y tengo que decir mientras nos machacamos con la kata del Juego de la vida de Conway me divertí, aprendí mucho TDD con Xavi Gost y mis parejas, terminé reventado tras las 5 iteraciones que hicimos. Programé con varios lenguajes: Groovy, Python, Javascript y Java; me quedé con las ganas de haberlo hecho también al menos con Ruby y C#(no habían lenguajes especialmente exóticos ).
Poco a poco, a base de iteraciones y de replantear el problema, los consejos de Xavi, los cambios de pareja… en la última iteración el código no tenía nada que ver con la primera. Y siendo Java el lenguaje de la última iteración, aún siendo el más ceremonioso que utilicé el sábado fue el que quedó más bonito… y para rematar nos dio tiempo a implementar lo suficiente para pasar las 4 reglas del juego de la vida!
En fin, que sí, que espero repetir experiencia de nuevo, hubo mucha gente con la que me quedé con las ganas de programar, aparte de otros que ni pudieron venir. Y si no es un code retreat… ¿quizás un coding dojo?
Por otro lado, yo he recopilado las cuentas de twitter de los asistentes(no sé si me dejo a alguien) y Rubén Mur, que estaba pendiente de que no faltase de nada en ningún momento y no conseguimos animarle para que le diera al código , estuvo grabando y publicando algunos ratos por streaming, estos son los videos:
Y por supuesto, después nos fuimos de cañas, luego por el tubo a cenar de tapeo y rematamos la noche tomando algo en algunos garitos del casco
Enlaces relacionados con software Mac y programación Cocoa:
Mac.AppStorm es un sitio dedicado a hacer revisiones de software para Mac. Además de las revisiones de aplicaciones ofrece artículos de opinión, entrevistas a desarrolladores, y las reuniones de aplicaciones, que son comparativas o selecciones de aplicaciones. Un buen sitio para conocer el mejor software para Mac y estar informado de las novedades de aplicaciones.
365Cocoa es un blog que ofrece trozos de código de Cocoa, uno por día durante un año. Los publica Pieter Omvlee que es el programador de Bohemian Coding, el creador de programas como Sketch y Drawit. Por cierto que a Pieter es uno de los programadores entrevistados en Mac.AppStorm.
Pure Reader es un plugin para Safari y otros navegadores que cambia el aspecto de Google Reader y lo convierte en un clon del programa Reeder. ¡ Hay que ver lo que se puede hacer con las CSS y un poco de imaginación !
Para los que todavía no sepan, hace ya algún tiempo Oliver Widder ha publicado un libro (version impresa o pdf) basado en el excelente cómic Geek & Poke.
Espero que lo disfruten los que se sientan aludidos...
y como enfrentar un proyecto de BPM???, primero hay que entender que es un proyecto diferente a un proyecto tradicional de TI donde las fases mas comunes son:
Análisis, Diseño, Desarrollo, Despliegue y Operación
En este tipo de proyectos se tiene como objetivo la automatización de procesos, al contrario los proyectos de BPM se basan en el analisis del proceso, de ser necesario modificarlo y finalmente implementarlo y monitorearlo, como lo explica el siguiente artículo
Uno de los puntos importantes a considerar al adoptar una estrategia-herramienta de BPM es el ciclo que se debe cubrir dentro de un proceso de negocio, bpmenterprise lo menciona:
El 16 de enero de 2008, Sun compró MySQL, y posteriormente, el 20 de abril de 2009, Oracle compró Sun, lo que viene a decir que desde enero de 2008, el servidor de base de datos MySQL, ha dejado de estar en manos de los ingenieros de MySQL AB.
Llevo usando MySQL desde la versión 3.23 del 2000, atraído por su simplicidad, calidad, y elevado rendimiento. He podido constatar como nuevas versiones, no sólo añadían mayores capacidades, sino que el desempeño también mejoraba.
Con la paulatina pérdida de control, hemos visto como características prometedoras, han quedado abandonadas si uno es mal pensado, por intereses comerciales de los nuevos dueños. Me estoy refiriendo a cosas como el motor María como reemplazo de MyISAM, y Falcon como reemplazo de InnoDB.
Echando un vistazo al histórico de versiones, vemos como la falta de criterio evolutivo es más que patente.
Sin embargo, el quid de la cuestión de esta nota, es una extraña particularidad que me he encontrado en el trabajo, y que es que determinados procesos con queries intensivas, han venido siendo entorno a 10 veces más lentos con las versiones en activo 5.1 y 5.5, que lo eran con las anteriores 5.0, y que casualmente se lanzaron cuando Sun era el dueño.
A continuación os doy algunas comparativas entre versiones de MySQLdel mencionado proceso:
Versión
Fecha lanzamiento
Tiempo (s)
MySQL 5.0.30 Stable
04/01/2007
24
MySQL 5.0.77 Stable
30/09/2009
15
MySQL 5.0.91 Stable
05/05/2010
14
MySQL 5.1.50 Stable
13/08/2010
184
MariaDB 5.1.50 Stable
08/09/2010
182
MySQL 5.1.52 Stable latest
12/10/2010
187
MySQL 5.2.3 Falcon Alpha
08/02/2007
16
MariaDB 5.2.2 Gamma
28/09/2010
191
MySQL 5.5.6 RC
13/09/2010
166
MySQL 6.0.11 Falcon Alpha
05/11/2009
171
En un futuro artículo os comentaré las opciones que tenemos para seguir contando con un SGBD de calidad, sin la amenaza subyacente de los intereses de "el caro".
El 16 de enero de 2008, Sun compró MySQL, y posteriormente, el 20 de abril de 2009, Oracle compró Sun, lo que viene a decir que desde enero de 2008, el servidor de base de datos MySQL, ha dejado de estar en manos de los ingenieros de MySQL AB.
Llevo usando MySQL desde la versión 3.23 del 2000, atraído por su simplicidad, calidad, y elevado rendimiento. He podido constatar como nuevas versiones, no sólo añadían mayores capacidades, sino que el desempeño también mejoraba.
Con la paulatina pérdida de control, hemos visto como características prometedoras, han quedado abandonadas si uno es mal pensado, por intereses comerciales de los nuevos dueños. Me estoy refiriendo a cosas como el motor María como reemplazo de MyISAM, y Falcon como reemplazo de InnoDB.
Echando un vistazo al histórico de versiones, vemos como la falta de criterio evolutivo es más que patente.
Sin embargo, el quid de la cuestión de esta nota, es una extraña particularidad que me he encontrado en el trabajo, y que es que determinados procesos con queries intensivas, han venido siendo entorno a 10 veces más lentos con las versiones en activo 5.1 y 5.5, que lo eran con las anteriores 5.0, y que casualmente se lanzaron cuando Sun era el dueño.
A continuación os doy algunas comparativas entre versiones de MySQLdel mencionado proceso:
Versión
Fecha lanzamiento
Tiempo (s)
MySQL 5.0.30 Stable
04/01/2007
24
MySQL 5.0.77 Stable
30/09/2009
15
MySQL 5.0.91 Stable
05/05/2010
14
MySQL 5.1.50 Stable
13/08/2010
184
MariaDB 5.1.50 Stable
08/09/2010
182
MySQL 5.1.52 Stable latest
12/10/2010
187
MySQL 5.2.3 Falcon Alpha
08/02/2007
16
MariaDB 5.2.2 Gamma
28/09/2010
191
MySQL 5.5.6 RC
13/09/2010
166
MySQL 6.0.11 Falcon Alpha
05/11/2009
171
En un futuro artículo os comentaré las opciones que tenemos para seguir contando con un SGBD de calidad, sin la amenaza subyacente de los intereses de "el caro".
Desde que salió PHP 5.3 Luis y yo nos hemos preguntado para qué leches podíamos usar esas tan celebradas nuevas cojo-closures que la última versión de PHP nos iba a ofrecer.
No es que sea nada nuevo. Estamos hartos de usarlas en JavaScript, donde la propia naturaleza del lenguaje y de los mecanismos que acostumbramos a usar para todo nos animan a usarlas constantemente. Una Closure no es más que una función creada on-the-fly para hacer algo y, para más inri, tampoco es que sea la repera de elegante si lo piensas en frío… ¿una función que me saco de la chistera? ¿esto no iba de orientación a objetos y tal?
Si conseguimos no rasgarnos las vestiduras, pronto nos daremos cuenta de que poner una Closure o dos en nuestras vidas nos hará mucho más felices. Prueba de ello es la clase que os pongo más abajo.
Os animo a echarle un vistazo al comentario de jeppe dot dyrby at gmail dot com en la documentación de la función vsprintf de PHP. De modo muy resumido, esto es lo que propone:
function dsprintf(){// Buscar tags con forma %(ñañaña)t// Pasar por dsprintfMatch() cada resultado para obtener la sustitución$string=preg_replace('/\%\((.*?)\)(.)/e','dsprintfMatch(\'$1\',\'$2\',\$data,$used_keys)',$string);// Devolver la cadena sustituida}function dsprintfMatch($m1,$m2,&$data,&$used_keys){// Relleno para que los argumentos %t sean compatibles con los %(ñañaña)t// Devuelve la sustitución}
¿A que se oye chirriar esa línea con el preg_replace?
En primer lugar, señores de PHP, ¿por qué se le puede pasar como argumento de sustitución el nombre de una función cuando existe la función preg_replace_callback()?
Dejando esta cuestión a un lado, esta es la implementación que uso, con orientación a objetos, closures y algodón de azúcar rosa:
class DSprintf {public$text;public$arguments;privatefunction DSPrintf($text,array$arguments){$this->text=$text;$this->arguments=$arguments;}publicfunction create($text,array$arguments){returnnew DSprintf($text,$arguments);}publicfunctionexec(){if(!$this->hasArguments())return$this->text;$that=$this;returnpreg_replace_callback('/\%\((.*?)\)/msi',function($matches) use ($that){return$that->arguments[$matches[1]];},$this->text);}privatefunction hasArguments(){returncount($this->arguments)>0;}}// Usage:$input="Hola %(cosa)!";$arguments=array('cosa'=>'Mundo');$output= DSPrintf::create($input,$arguments)->exec();// Now $output contains "Hola Mundo!"
Básicamente hago lo mismo, en una clase con Factory Method, realizando los siguientes cambios:
He eliminado la parte del tipado de los argumentos. Nunca he entendido esto en el printf.
He reducido la funcionalidad. Solo se admiten argumentos con el formato %(ñañaña). Si quieres usar %s ya tienes toda la gama de printf.
He sustituido preg_replace(caca,culo,pedo) por preg_replace_callback(caca, CLOSURE, pedo)
Si os fijáis en la documentación de preg_replace_callback, veréis un montón de ejemplos bastante buenos que dan muchas pistas para llegar a esta implementación.
En cuanto a la Closure, es bien sencilla y creo que solo habría que que aclarar que $matches es algo que la función preg_replace_callback() le va a pasar siempre al callback, por lo que tenemos que declararla con ese parámetro. La directiva use() que empleo después de la declaración sirve para pasarle la instancia actual al contexto de ejecución de la Closure, de modo que el array de argumentos esté disponible y se puedan resolver las sustituciones. El cuerpo de la función no hace gran cosa: solo busca el argumento a sustituir en el array de argumentos de nuestra instancia y devuelve la sustitución que hay que enchufar en su lugar.
Sencillo y limpio, ¿no creéis?
Preguntitas para la audiencia: ¿Se os ocurre algún uso práctico más para las Closures? ¿Las estáis usando para algo actualmente?
El pasado 27 de noviembre estuvimos presentes en el Joomla! Day 2010 celebrado en Valencia dando una charla sobre la usabilidad del gestor de contenidos Joomla!. En concreto, nuestra presentación consistió en una introducción sobre los conceptos básicos de usabilidad, para después pasar a la presentación de resultados de las pruebas de usabilidad con usuarios que habíamos efectuado durante las semanas anteriores sobre la interfaz de administración de Joomla!.
Vamos a estar más de 20 personas programando con Xavi Gost como facilitador. Estaremos programando en parejas, procurando practicar TDD y seguro que aprendiendo mucho unos de otros. Al menos yo espero programar con algún lenguaje que no conozco, refrescar otros que toco menos habitualmente, ver formas diferentes de enfocar el mismo problema… y sobre todo pasarlo bien!
Me pareció impresionante que en unas 2 horas ya se cubrieran las 20 plazas que habían de inicio y que vengan varias personas de fuera. La verdad que así da gusto andar ayudando a mover cosas
El evento se llevará a cabo en el Digital Water Pavilion(en Av. Francia s/n, muy cerca de la estación Intermodal Zaragoza-Delicias). Muy adecuado hacer un evento para programadores en un edificio programable
Os dejo unas fotos que hice el otro día para que os hagáis una idea los que no sepáis cuál es el edificio:
El framework Pimento Data Services nos permite realizar el “lazy loading” de una asociación que haya sido configurada como “lazy” en JPA. Para ese tipo de asociación el framework envía al cliente solamente “proxies”, no los datos reales, los datos reales serán cargados en el momento que se invoque el método “initialize” de la clase EntityManager, y no obtendremos una excepción del tipo LazyInitializationException. Veamos cómo funciona a través de un ejemplo.
El ejemplo
Lo primero será descargar el framework de aquí. Luego creamos un proyecto de tipo “Dynamic Web Project” con las siguientes características:
Nombre del proyecto: LazyPimentoServer
Target Runtime: En nuestro caso usaremos Apache Tomcat 6, pero puede utilizarse cualquier otro que se haya configurado.
Versión del módulo Web Dinámico: 2.5
Configuración: Configuración por defecto para Apache Tomcat 6.0
Cambiamos la carpeta donde se compilarán las clases a “LazyPimentoServer/WebContent/WEB-INF/classes”.
Una vez creado el proyecto copiamos el contenido de la carpeta “server/web/WEB-INF/lib” de la distribución del framework en “WebContent/WEB-INF/lib” de nuestro proyecto. Sustituimos el archivo de HSQLDB por el controlador JDBC de MySQL, y copiamos de la carpeta “server/release” los archivos “cinnamon-core”, “cinnamon-reflect” y “pimento-core”. Necesitamos copiar también el paquete “javassist”, este lo podemos encontrar en la distribución de Spring con dependencias.
Creamos una carpeta denominada “config” dentro de “WebContent/WEB-INF” de nuestro proyecto y copiamos los archivos “jpa-spring.xml” y “pimento-spring.xml” en “server/web/WEB-INF/config” en la distribución del framework; también copiamos el archivo “dp.properties.template.mysql” de “server/web/WEB-INF/config/db-templates” como “db.properties” en “WebContent/WEB-INF/config” de nuestro proyecto y ajustamos los valores de la conexión a la base de datos. Como estamos en fase de desarrollo ponemos “hibernate.hbm2ddl.auto=update”.
Finalmente el archivo “web.xml” de nuestro proyecto queda así:
Seguidamente crearemos las entidades asociadas:
Project
Task
Como vemos son dos entidades JPA con anotaciones de Pimento que indican que serán gestionadas por éste. La entidad “Project” tiene una asociación con la entidad “Task” de tipo OneToMany configurada como “lazy”, lo que implica que cuando se cargue una instancia de “Project” no se cargarán en ese instante las instancias de “Task” asociadas con ésta. En este caso el framework enviará al cliente “proxies” que serán utilizados para cargar los datos reales. Veamos cómo funciona esto desde la UI, pero primero cargaremos algunos datos en la base de datos:
Creamos un proyecto Flex con las siguientes características:
Nombre del proyecto: LazyPimentoClient
Tipo de aplicación: Web
Seleccionamos el SDK por defecto
Como tecnología del servidor no seleccionamos ninguna
Como carpeta de salida seleccionamos la carpeta WebContent del proyecto LazyPimentoServer que creamos anteriormente.
Nuestra interface de usuario sería algo como esto:
Inicialmente cargaremos una instancia de Project e inspeccionaremos el contenido de su propiedad “tasks”, luego cargaremos las instancias de “Task” asociadas mediante el método “initialize” de la clase EntityManager, las cuales mostraremos en el “DataGrid”.
Para estructurar mejor el proyecto nos auxiliaremos del framework Robotlegs. Lo primero que haremos será incluir en el proyecto las librerías del framework Pimento y Cinnamon. Copiamos en la carpeta “libs” del proyecto los archivos “cinnamon-1.1.0.swc” y “pimento-1.1.0.swc” que se encuentran en la carpeta “client\release” de la distribución, incluimos también “spicelib-core-2.0.1.swc” y “spicelib-reflect-2.0.1.swc” de la carpeta “client\lib” y la librería del framework Robotlegs.
Creamos luego las clases en ActionScript que representan las entidades:
Project
Task
La configuración del framework en el cliente comienza con la creación de una instancia de la clase “PimentoConfig”, a través de la cual podemos obtener el “EntityManager” que usaremos para invocar las operaciones de persistencia. La clase PimentoConfig necesita conocer el URL de la aplicación JEE que a través de Cinnamon recibirá las solicitudes del cliente para invocar las operaciones de persistencia, específicamente el URL al servlet “service”. En nuestro caso cargaremos esta información de un archivo xml externo. El comando que hace todo esto y además carga la instancia de “Project” que insertamos en la base de datos es el siguiente:
Si corremos la aplicación con el “debugger” y nos paramos dentro del método loadResult veremos que el tipo de la propiedad “tasks” de Project no es un “Array” como está definido sino de tipo “ArrayProxy”.
Una vez cargada la instancia de Project, ante el evento “Click” del botón se ejecuta el comando que carga los datos de la asociación:
El método que carga los datos de la asociación es “initialize”, de “EntityManager”, se le pasa como argumento la propiedad “tasks” de la instancia de “Project” previamente cargada.
Una vez más, si corremos la aplicación con el “debugger” y nos paramos dentro del método “initializeResult” veremos que el tipo de la propiedad “tasks” ha cambiado de “ArrayProxy” a “Array”, conteniendo las instancias de “Tasks” asociadas.
El código fuente del la aplicación, cliente y servidor se puede descargar de aquí.
Conclusiones
Hemos visto como Pimento Data Services nos permite hacer “lazy loading” de entidades directamente desde ActionScript de una forma verdaderamente simple. Tan solo debemos poner las anotaciones en la entidad Java y el framework se encarga del resto, es una lástima que Pimento y Cinnamon no soporten ninguna funcionalidad que permita hacer sincronización de datos entre varios clientes. ¿Alguien se anima?
El último roadmap de Embarcadero, lo deja claro. Durante la primera mitad de 2011, se espera una preview del compilador de Delphi con generación nativa de código x64. Inicialmente será solamente una versión del compilador por linea de comandos DCC, que a medida que madure se integrará en el IDE (Pulsar), y posteriormente se adaptará también a C++ Builder (Wheelhouse). Sin embargo es poco probable que todo ello esté disponible oficialmente antes de la siguiente versión de RAD Studio a finales de 2011.
Más adelante, deberían aparecer versiones para Mac y Linux (Commodore), que permitirán un portado sencillo de aplicaciones existentes mediante una VCL multi-plataforma, y sin la sobrecarga que existe actualmente con librerías como Qt.
A día de hoy, ya hay indicios de versiones en desarrollo de DCC64, por lo que parece que esta vez si que van dentro de plazo.
Os sorprendería la cantidad de aplicaciones que podéis estar utilizando, y que están compiladas con Delphi, obteníendose mejoras de rendimiento si los desarrolladores utilizaran la versión preliminar x64 para recompilar: