Noticias Weblogs Código

Blog Bitix

Introducción y características de Docker

October 30, 2014 07:01 PM

Docker

Docker es una de las herramientas de la que se está hablando mucho, esto es así ya que tiene varios aspectos interesantes que cambian la forma de desarrollar aplicaciones. Docker es una forma de ejecutar procesos de forma aislada pero también se compone de herramientas para construir imágenes y un repositorio para compartirlas.

Al contrario de la virtualización Docker no emula o virtualiza una máquina y su sistema operativo con lo que los procesos son mucho más ligeros y hace que el hardware pueda ser aprovechado más al poder aumentar la densidad de los servicios en una misma máquina. Los contenedores y servicios incluidos en ellos inician muy rápidamente, en pocos segundos. Además, no es necesario el sistema de archivos completo del sistema operativo invitado con lo que docker usa una fracción de espacio de almacenamiento necesario en la virtualización.

La tecnología de contenedores no es nueva y también está disponible en otros sistemas operativos como OpenVZ también en Linux, FreeBSD Jails o los contenedores de Solaris.

Docker tiene varias características interesantes. Es ligero ya que no hay virtualización aprovechándose mejor el hardware y únicamente necesitando el sistema de archivos mínimo para que funcionen los servicios. Los contenedores son autosuficientes (aunque pueden depender de otros contenedores, por ejemplo, un wordpress que necesita una base de datos mysql) no necesitando nada más que la imagen del contenedor para que funcionen los servicios que ofrece. Las imágenes de docker son portables entre diferentes plataformas el único requisito es que en el sistema huésped esté disponible docker. Es seguro, pudiendo hacer que los contenedores se comuniquen por un túnel solo disponible para ellos, los contenedores están aislados en el sistema mediante namespaces y control groups.

Para los desarrolladores tiene las siguientes ventajas:

  • Podemos disponer de un entorno de desarrollo (devbox) o servicio en varios minutos/horas en vez de algún día. Esto es así porque la configuración y los servicios necesarios están automatizados en la construcción de las imágenes de los contenedores mediante Dockerfiles.
  • Al estar los servicios en contenedores no hace falta instalarlos en la máquina en la que son alojados, de forma que podemos disponer de los servicios y después eliminarlos de forma sencilla sin “ensuciar” el sistema huésped.
  • Nos permite tener versiones más parecidas o iguales a las usadas en producción. Por ejemplo, en Arch Linux nos permite tener un mysql de la distribución Ubuntu usando la misma versión.

El registro de contenedores de Docker es una forma colaborativa de ofrecer imágenes. Hay disponibles multitud de contenedores con los servicios más populares: MySql, PostgreSQL, Redis, Nginx, WordPress, …

Para los administradores de sistemas tiene las siguientes ventajas:

  • Pueden proporcionar entornos similares o iguales a los entornos de pruebas, QA o producción independientemente de la distribución que se use.
  • Es posible desplegar un contenedor en cualquier infraestructura Linux.
  • La creación de los contenedores puede ponerse bajo un sistema de control de versiones.

En el siguiente vídeo y presentación muy completa están ampliados muchas de sus posibilidades y funcionalidades.

Una vez conocidos los aspectos básicos y en que se diferencia docker de la virtualización así como el caso de uso de por ejemplo un devbox o disponer de entornos similares a los de producción de una aplicación, en el siguiente artículo comentaré cómo instalar docker, cómo empezar a usarlo, cómo obtener imágenes de servicios y pararlos y administrarlos.

Referencia:
Docker
Seguridad Docker
Four ways Docker fundamentally changes application development
Docker, qué es y sus principales características

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

Off shore vs on shore

October 29, 2014 02:08 PM

Off-shore vs. On-shore in the development space http://www.batimes.com/articles/off-shore-vs.-on-shore-in-the-development-space.html

» Leer más, comentarios, etc...

Picando Código

Humble InDIE Bundle 13, ¿vale la pena comprarlo?

October 29, 2014 01:00 PM

Humble Indie Bundle 13

Durante los primeros tiempos de los Humble Indie Bundle, solía postear en el blog por cada nueva edición como un suceso importante. Pero con el tiempo fueron perdiendo un poco de relevancia en el hecho de ser un evento trascendente en la comunidad de GNU/Linux por traer más juegos a nuestro querido sistema operativo, además de ser libres de DRM :D

Pero – se puede decir “por suerte”, y no a la vez – la situación cambió. Hoy en día recibo demasiados correos notificándome de nuevos bundles cada semana. Algunos siguen ese ideal de ser multiplataforma y sin DRM, unos muchos no. Lo importante es que el Humble Indie Bundle no perdió su esencia, y sigue constando de los mismos principios: Juegos al precio que elijas, libres de DRM, y multiplataforma (GNU/Linux, Mac y Windows). Si bien aquella excepción en la que se liberó el código no se volvió a cumplir (que yo sepa), hay cada vez más juegos portados al sistema gracias a Humble Bundles (y en otra capacidad a Steam).

Volviendo al tema, resulta que hay una decimo tercera edición del Humble Indie Bundle, y con 3 nuevos ports a Linux, se han alcanzado los 100 juegos migrados a esta plataforma.  La gente de Humble Bundle cuenta que su fundación se construyó sobre la idea de ayudar a desarrolladores de videojuegos independientes a mostrar sus juegos multiplataforma y libres de DRM al mundo. Para que un juego esté en el Humble Indie Bundle, toman en consideración si es multiplataforma y libre de DRM. Si no lo es, intentan hacer que pase.

Cuentan con sus portadores de juegos propios y trabajan también con terceros para hacer que los juegos se puedan usar en GNU/Linux, Android, Mac y hasta la web con asm.js. Como dicen, no es tan fácil hacer la transición a una plataforma distinta, y muchas veces se trata de juegos de estudios independientes que no cuentan con los recursos para hacer dicho trabajo. Por eso los Humble Bundle siguen siendo relevantes.

En lo que va de la vida de los Humble Bundle (¿se quieren sentir viejos? ¡El primero fue en 2010!), los usuarios de GNU/Linux han pagado en promedio 1 dólar más que los de Mac y 2.60 más que los usuarios de Windows. Si bien en cantidad los usuarios de Linux somos generalmente menos que los de Windows o Mac, siempre pagamos mejor :)

Humble Indie Bundle 13

Humble Indie Bundle 13

En esta decimo tercera entrega del Humble Indie Bundle contamos con los siguientes juegos:

  • OlliOlli – Skate en 2D que a mí me hace acordar un poco a California Games, aquel juego con el que tanto me viciaba en la 486.
  • Insanely Twisted Shadow Planet – 2D de acción y aventura. Es bastante loco el trailer así que tendré que probarlo para ver de qué se trata…
  • Tower of Guns – Un FPS que supuestamente se puede terminar en una hora o dos, pero no es fácil. Me intriga, veremos (si bien no soy fanático de los FPS podría probarlo por un tema de completismo y lo poco que lleva en teoría terminarlo).

Pagando más del promedio ($ 6.49 al momento de escribir esto):

  • Amnesia: A Machine for Pigs – De los creadores de Amnesia: The Dark Descent, el juego que metía tanto miedo que nunca me animé a jugar más que unos minutos en la oscuridad… De repente muestra un poco de la cruda y sádica realidad que hace que la panceta que tanto le gusta a tanta gente llegue a la mesa.
  • Jazzpunk – No tengo ni idea de qué trata este juego y después de ver el trailer la cosa no mejoró. Es de Adult Swim, ¿así que en una de esas está bueno?
  • Risk of Rain – Uno de los que me llamó la atención, acción y plataformas con disparos, enemigos y jefes al azar. Hasta el 28 de noviembre tengo mi clave de Steam y 3 más para regalar. Así que si quieren una clave de este juego, dejen un comentario en esta entrada y le regalaré las llaves a los primeros tres que las pidan, así de fácil.

Pagando desde $ 12 y más:

  • Shadowrun Returns – Elfos, trolls, orcos y enanos mezclado con magia en un ambiente futurista de mercenarios, tecnología, magia y leyendas. La temática es interesante, veremos qué tal, al ver el trailer me dieron ganas de al menos ver de qué se trata…

Mi veredicto final es: Sí, se compra. De hecho lo compré enseguida. Vengo comprando los Indie Bundle más que nada por tradición, pero en éste particularmente puede ser que me enganche con alguno de los juegos. Lo interesante es que han sido una gran mano en el tema de hacer más accesible los juegos para GNU/Linux, y eso nunca viene mal. Si bien no son software libre, son un paso en la dirección correcta al momento en que se toma en cuenta la plataforma cuando un juego nuevo se lanza “para PC”. Es todo parte del proceso, de a poquito se van ganando batallas.

Les dejo el trailer a continuación, y los invito a visitar el Humble Indie Bundle y pagar el precio que elijan para los juegos que se ofrecen:

» Leer más, comentarios, etc...

Picando Código

Fase 3 del universo cinematográfico de Marvel

October 29, 2014 12:00 PM

Esta es la mejor época en la que podría haber nacido para disfrutar del cine de super héroes. Gracias Marvel por todo lo anunciado, y todavía queda una supuesta película sin nombrar.

La segunda fase del universo cinematográfico de Marvel termina en 2015 con Avengers: Age Of Ultron (de la cual ya pudimos disfrutar el trailer), seguida de Ant-Man. A partir de ahí empieza la tercera fase. Hasta cumplir casi 34 años voy a tener películas de Marvel basadas en cómics para mirar en el cine:

Marvel Fase 3

Marvel Fase 3

2016
6 de Mayo – Captain America: Civil War
4 de Noviembre – Doctor Strange

2017
5 de Mayo – Guardianes de la Galaxia 2
28 de Julio – Thor: Ragnarok!
3 de Noviembre – Black Panther

2018
4 de Mayo – Avengers: Infinity War, Parte 1
6 de Julio – Captain Marvel
2 de Noviembre – Inhumans

2019
3 de Mayo – Avengers: Infinity War, Parte 2

¡Películas de Captain Marvel y los Inhumanos! (las demás no fueron tanta sorpresa). La tercera y cuarta película de Avengers involucran a Thanos con el Infinity Gauntlet y seguramente junten a todos los personajes del universo cinematográfico en su contra. No podría ser más feliz :D

» Leer más, comentarios, etc...

Picando Código

Mi resumen de RubyConf Argentina 2014

October 28, 2014 03:09 PM

Para el mayor disfrute de la lectura de este post, Picando Código recomienda leerlo mientras se escucha esta canción.

Pasó otra edición de RubyConf Argentina y fue otro éxito en la comunidad RubySur. Desde el punto de vista objetivo supongo que se puede afirmar tranquilamente que la conferencia fue un éxito: Buen nivel de charlas, gran asistencia, involucramiento del público, se tomaron muchos litros de café y agua, y por lo que se escuchó y leyó la gente pasó muy bien.

RubyConf Argentina 2014

RubyConf Argentina 2014

El primer día empezó con la charla del amigo Jano González, para arrancar la conferencia con todo. Las intervenciones de Jano siempre rinden. En esta ocasión en particular habló sobre Microservicios y cómo los usan en la arquitectura de Soundcloud.

El siguiente fue Lucas Videla que dió una charla de flujos de desarollo con Git que estuvo genial. En uno de los breaks le pregunté a Lucas si da clases, porque se notaba experiencia en explicar las cosas de manera que desde el más principiante hasta el más avanzado se llevara algo (y se notó mucho trabajo en los diagramas que usó como complemento visual para entender mejor).

El día continuó con mucho calor y charlas muy buenas. Perdón que no haga un resúmen de cada una, mi memoria no es tan buena, y no hice como en otros tiempos que me llevaba una libretita donde iba anotando comentarios… Pero pueden leer otro resumen del evento en el blog de Lucas Videla.

El calor se debió a que estos días está habiendo temperaturas particularmente altas por la zona del Río de la Plata (se viene tormenta) y los aires acondicionados aparentemente tenían un problemita. Pero se corrigió para el segundo día y los asistentes, organizadores y oradores se aguantaron el calor que no fue suficiente para opacar lo bien que se estaba pasando.

Las siguientes charlas fueron de Hanneli Tavante sobre Ruby y Neo4j, Paul Smith sobre descarrilar la irracionalidad, Federico Carrone con concurrencia para Rubistas (no puede faltar una charla sobre concurrencia en una RubyConf), Ignacio Piantanida sobre RubyMotion y Damián Janowski sobre Redis.

Una de las charlas que mencioné en mi post anterior sobre RubyConf AR, fue la de Lu Escanellas (también conocida como raviolicode) sobre Algoritmos. Y debo decir que la charla superó mis expectativas. Estuvo genial, Lu demostró mucha cancha dando la presentación y es una de esas personas que cuando habla de algo se nota que sabe. Una sorpresa que me llevé fue que mencionó este blog para mostrar un ejemplo :D

Habló sobre complejidad y órdenes en algoritmos y un ejemplo de por qué esto importa cuando desarrollamos Ruby. Generó preguntas y muchos comentarios de pasillo de gente que quedó colgada con el tema, un éxito.

El día cerró con Emilio Gutter que habló de “mandamientos” o buenas prácticas y sugerencias para programar con Ruby. Después de eso hubo un tiempito para que todos pudiéramos ir a los respectivos lugares de alojamiento a asearse y cambiarse, y después asistir al drinkup auspiciado por Citrusbyte. Los drinkups son una excelente oportunidad para conocer gente del ambiente y compartir alguna bebida y experiencias.

El segundo día empezó con otra de las presentaciones que esperaba con alta expectativa, Patricio Bruna hablando sobre Docker. Patricio es un “impostor” según contó, administrador de sistemas volcándose al desarrollo. Estuvo genial, tanto en forma como en contenido, y me terminó de convencer de que tengo que empezar a usar más Docker y menos Vagrant en mis ambientes de desarrollo :)

Otro tema bastante interesante fue lo expuesto por Marta Paciorkowska, sobre programación, lenguajes y literatura. Presentó paralelismos entre el mundo de los escritores y los programadores, de esos temas que te hacen levantar un poco la cabeza del teclado y pensar a nivel más alto. Muy buena.

Se habló de varios temas más: análisis de datos por Juan Barreneche, EventMachine por Federico Builes, ArangoDb por Lucas Dohmen y construyendo un motor de búsqueda con JRuby y Lucene por Augusto Becciu.

Chris Hunt en RubyConf Argentina

Chris Hunt en RubyConf Argentina

Había comentado que la presentación de Chris Hunt también estaba entre las que más esperaba. Y no defraudó. Fue de esas presentaciones que te hacen explotar el cerebro, siguiendo la línea de lo que mostró en RubyConf Uruguay sobre memoria, esta vez para memorizar un cubo de Rubik y hasta resolverlo con los ojos vendados. Además de asombrarnos por su habilidad con el cubo, la puesta en escena es un espectáculo completo y digno de cualquier conferencia para nerds.

La jornada terminó con mi amigo Pote (también conocido como Pablo Astigarraga) con un keynote sobre el dilema de la simplicidad y su forma de ver y encarar la simplicidad a la hora de programar y cómo lo ayuda en su trabajo.

Después de eso un momento bastante emotivo con todos los organizadores de la conferencia. Todavía no se sabe si esta fue la última edición o volvería el año que viene. Pero seguramente no sea el mismo equipo hasta ahora. Por mi parte espero que sigan haciendo la conferencia por toda la eternidad.

A modo de conclusión, me llevé mucho de la conferencia:

Uno de los temas que reflexioné durante el viaje de vuelta fue el ambiente de unión que genera esta movida. Mientras que tantas cosas en nuestro día a día nos convencen de las diferencias entre las personas y nos ponen en contra los unos a los otros, ya sea por nuestro país de origen, género, religión, forma de programar, el lenguaje que elegimos, etc., sentí de RubyConf Argentina todo lo contrario. Realmente lo sentí como un evento que une a las personas y donde no podrían importar menos las banderas y fronteras ni otros factores que nos diferencien, estas cosas se celebran y nos une lo que tenemos en común.

RubyConf Argentina 2014

RubyConf Argentina 2014

Llegué a la comunidad Ruby hace unos años sin conocer a nadie, y me sentí bienvenido desde un principio. Estos eventos hicieron que cada vez tuviera más amigos en la comunidad. Son una de las oportunidades que tengo de volver a ver a la gente que fui conociendo de todos lados, y siempre es un factor muy importante para mí. Para una persona patológicamente tímida como yo, suma mucho acercarse a una comunidad como ésta. Así que estoy bastante agradecido por eso y por los nuevos amigos.

También siento que se cumplió el objetivo principal de la conferencia de llevarme muchas cosas en la cabeza para investigar, probar y aprender. Las charlas te inspiran y alimentan esa necesidad de aprender algo nuevo y experimentar con tecnologías que viste presentadas. Espero mantenerlo, es lo que más cuesta con la rutina del trabajo y demás, pero voy a hacer el esfuerzo de investigar esas cosas nuevas y compartirlas acá.

La gente de RubyConf Argentina 2014

La gente de RubyConf Argentina 2014

Como dije soy una persona tímida y de repente no muy expresivo, me resulta mas fácil escribir las cosas que decirlas en persona. Así que voy a aprovechar este espacio para agradecer muchísimo a Leandro López, Nicolás Cerrini, Cecilia Rivero, Lucas Florio, Ernesto TagwerkerMatias Owsianik y Sebastian Rabuini. Es terrible trabajo organizar una conferencia de este tipo, y valoro muchísimo que lo hayan hecho. Estoy muy agradecido por RubyConf Argentina y ha sido un evento super importante para mí. Así que gracias, muchísimas gracias :)

Las fotos son todas del album en Flickr de RubyConf Argentina:
https://www.flickr.com/photos/rubyconfar/sets/72157648949834642/

Ni bien me entere que están los videos de las presentaciones, lo comparto por acá.

» Leer más, comentarios, etc...

Variable not found

¡A Seattle! (episode IV)

October 28, 2014 02:04 PM



Este año, por cuarta vez consecutiva, tendré el placer de asistir dentro de unos días al MVP Global Summit, un macro evento anual organizado por Microsoft en el que reúne a todas las personas reconocidas como Most Value Professional para compartir novedades e intercambiar ideas y planes sobre las tecnologías con las que trabajamos a diario y, mejor aún, con las que trabajaremos dentro de algún tiempo.

Podéis imaginar lo que puede salir de una coctelera en la que introducimos algunos miles de personas procedentes de todos los rincones del mundo, técnicamente excepcionales en muchos casos, y figuras reconocidas y miembros de equipos de producto de Microsoft, compartiendo innumerables sesiones técnicas, debates y encuentros informales organizados durante los días de duración del evento. Una gozada.

Además, creo que este año el evento va resultar especialmente jugoso desde el punto de vista técnico, más que nada por las nuevas tecnologías y herramientas que están empezando a vislumbrarse por el horizonte y que todos ya conocemos :)

Y por supuesto, también es una oportunidad de disfrutar de la compañía de amigos que sólo coincidimos en persona en este tipo de eventos, una o dos veces al año como máximo. Y, por qué no, para seguir conociendo Seattle y sus alrededores, que estas oportunidades hay que aprovecharlas ;)

¡Nos vemos a la vuelta!

» Leer más, comentarios, etc...

Variable not found

Mejoras en bloques try/catch de C# 6

October 28, 2014 12:52 PM

imageSeguimos con la serie donde vamos desgranando las novedades de C# 6, y en esta ocasión vamos a ver algunas mejoras en el uso de bloques try/catch, a las que seguro podremos sacar buen partido.

En este post trataremos dos temas distintos. En primer lugar, comentaremos la introducción del soporte de await en bloques catch/finally, y seguiremos con la nueva capacidad de filtrado de excepciones.

Vamos a ello :-)

Soporte de await en bloques catch/finally

Esta nueva característica cubre una pequeña ausencia presente en las versiones anteriores del lenguaje de la que, sinceramente, no me había dado cuenta hasta la fecha. Resulta que en las versiones de C# anteriores a la 6, no estaba permitido utilizar await para esperar la finalización de una llamada asíncrona en bloques catch y finally. Por tanto, un código como el siguiente lanzaba un error de compilación:

image

Como curiosidad, el motivo de que el uso de await no estuviera soportado en este tipo de bloques en las versiones anteriores del lenguaje era simplemente "porque era muy difícil de implementar" (palabras textuales).

No sé a vosotros, pero a mí incluso me ha sorprendido que no se pudiera hacer antes. Seguro que si no lo he echado en falta es porque no me he encontrado hasta ahora con la necesidad de hacerlo, lo que puede indicar que tampoco es algo habitual (al menos por mi parte, claro) pero bueno, está bien saber que ya podremos usarlo con normalidad.

Filtros de excepciones

Hasta ahora, la granularidad de los bloques catch  de C# es a nivel de tipo de excepción. Es decir, tras un try normalmente encontramos tantos catch como tipos de excepción distintos queremos controlar, indicando así dónde queremos que se gestione la excepción cuando se produzca. Podemos ver un ejemplo del código habitual en el lateral.

Aunque este enfoque es válido en muchas ocasiones, hay otras donde sería interesante poder tener un mayor control a la hora de decidir si queremos que un bloque catch concreto gestione una excepción.

Para ello, C# 6 incorpora los nuevos exception filters, que son condiciones adicionales que podemos añadir a cada cláusula catch de forma que, si no se cumplen, el bloque será ignorado y se seguirá buscando en el resto de catchs si hay alguno que puedan manejar la excepción.

Nota: efectivamente, esto existe en VB.NET desde el principio de los tiempos. Aunque a veces pueda parecer lo contrario, no siempre C# va por delante ;)

La sintaxis de estos bloques es la siguiente:


Como podéis observar, la cosa consiste simplemente en añadir condiciones a las cláusulas catch, de forma que la excepción sólo será tratada en ese bloque si la condición evalúa a cierto. En caso contrario, se continuarán evaluando el resto de catchs hasta encontrar uno capaz de gestionar la excepción. Por ejemplo, en el caso anterior, un una excepción ServerException cuya propiedad HttpCode valga 503 será evaluada por el catch final.

Fijaos que con las versiones de C# anteriores a la 6 no sería tan sencillo solucionar este escenario. Nos veríamos obligados a introducir un único catch para la excepción ServerException y decidir en su interior si debemos tratarla, pero en caso contrario no podremos dejarla fluir para que otros catch posteriores la traten. A lo sumo podríamos relanzarla, pero el resultado tampoco sería el mismo.

Por supuesto, las condiciones pueden contener cualquier tipo de expresión booleana, como en el siguiente ejemplo:



Y aprovechando esta capacidad, es posible hacer uso y abuso de estos filtros para realizar tratamiento lateral de excepciones, es decir, realizar determinadas tareas cuando una excepción se detecta, pero permitiendo que el resto de catchs sean evaluados. Por ejemplo, en el siguiente código se guardan las excepciones ServerException en el log, pero el tratamiento final de la excepción se realizará en el último catch porque el filtro siempre retorna false:



En definitiva, de nuevo estamos ante unas novedades no muy espectaculares, pero sí útiles para cubrir escenarios que con las versiones anteriores de C# no podíamos solucionar de forma tan directa.

Otros posts de la serie sobre C# 6:
Publicado en Variable not found.

» Leer más, comentarios, etc...

Arragonán

Semana 333

October 27, 2014 06:38 PM

Aunque este mes se me está haciendo un tanto largo, la semana empezó bien. Con la excusa de que Iván apuraba su última semana de vacaciones en estas tierras y que Mark también se volvía para una buena temporada a Australia, montamos una cena con una buena representación de cachirulistas.

Hacía días que no nos juntábamos a comer o cenar, aunque en esta ocasión ni si quiera intentamos grabar un podcast :P.

Tras una mañana itinerante me pasé a trabajar un rato (el suficiente para que me trolearan) por los HQ de Dodo Cojo.

De improvisto, Iván se animó a preparar para el viernes un Taller de Atlasboard, una herramienta escrita en node.js para montarte tus propios dashboards. Me entraron ganas de trastearlo y volver a flirtear con el mundillo node, otra cosa será sacar tiempo para ello… Y después del taller, como es menester, unos cuantos nos fuimos a tomar unas cañas.

En cuanto a proyectos actuales:

  • En Nort estuve implementando algunos cambios de requisitos en la aplicación móvil, también arreglando varios temas relacionados con la seguridad del backend y un bug bastante problemático en el frontend. Lo habitual estos últimos meses con este proyecto absorbiendo la mayor parte de mi tiempo.
  • Estuve pegándole un vistazo a HelpScout, y decidí que por ahora voy empezar a usarlo para el soporte de Minchador.

Buena semana.

» Leer más, comentarios, etc...

carlosrovira.com

15 años después…

October 27, 2014 06:26 PM

Parece ser que hoy se cumplen 15 años de la edición del álbum Metropolis, Part 2: Scenes From A Memory creado por el grupo de rock progresivo Dream Theater.

Este disco es una de esas maravillas que merecen ser escuchadas aplicando todos los sentidos. Para mi fue todo un descubrimiento en su época (hablamos del año 1999) y esta noticia de su quinceavo cumpleaños no deja de sorprenderme y generar varias respuestas emocionales de carácter personal en mi. Por un lado, me obliga a ser consciente del tiempo transcurrido y como, a veces, este se expande o contrae en nuestra memoria haciendo que determinadas cosas parezcan tan lejanas en el tiempo y otras tan cercanas. Por otro, ser asaltado por un “golpe de realidad” donde nuevamente se pone de manifiesto la enorme cantidad de vivencias transcurridas desde que tenía 26 años. Para que os hagáis una idea, la época del disco convive en el tiempo con una gran cantidad de cambios en mi vida encabezados por el traslado de residencia a Madrid y el comienzo de una nueva vida y todo lo que eso conlleva.

En lo que respecta a la obra en cuestión. Se trata de una obra conceptual de rock progresivo que cuenta una historia con tintes dramáticos, sobrenaturales, combinando el misterio y el asesinato. En palabras de Wikipedia:

Scenes From a Memory es un álbum conceptual que narra una única historia, acerca de un joven que descubre su pasado, el cuál está relacionado con el amor, asesinato e infidelidad de Victoria Page.

El albumen comienza con la regresión del joven y la historia se va desenvolviendo poco a poco durante los 76 minutos de duración. Una lectura de la página de wikipedia es un buen “companion” para la escucha y análisis de esta magnífica obra que une música y estructura literaria con elegancia y maestría.

Aprovecho la ocasión para rendir homenaje a esta pieza maestra (a la vez que hago introspección personal de estos 15 años a mis espaldas) y recomendaros que busqueis un rato para su escucha y disfrute. También recomendar Metropolis_2000:Scenes from New York donde se presenta en vivo este álbum de forma magistral.

» Leer más, comentarios, etc...

Cuaderno de software

Functional trick to compose Conditions in Jooq

October 27, 2014 07:21 AM

I’m starting to use Jooq in my projects and it’s been a very pleasing experience so far. I was starting to extract & refactor my own DSL from my Repositories to do something much less sophisticated when I stumbled upon Jooq and soon I realized that it would be much more productive to simply switch.

I like about Jooq that it doesn’t interfere with my business logic or my domain. I have an hexagonal architecture and I love that it just handles SQL generation with a nice builder DSL. It does one thing and it does it well.

In my case, due to the nature of some parts of my apps (out of the scope of this post), I need to dynamically add and combine conditions in my SQL queries and, Jooq being a builder DSL, I didn’t like to stop the statement creation on the where() step and the conditionally combine conditions one at a time. That leads to a lot of ugly if() blocks like in this example:

This is a very naive approach to SQL construction and it seems obvious to me that those if() blocks are getting in the way of my design. I recon that, at some point, I have to make them in order to, conditionally, add new WHERE clauses to the SQL. The question here lies on how to get rid of them.

My solution for the time being consist on applying little functional tricks that let me declaratively add conditions, but wrapping them in a class that does the if() out from my Repository’s code (enhanced thanks to a kind tweet reply by @JavaOOQ).

First I need a way to combine lists of conditions:

Then, I need the wrapper class to hide the if() blocks:

With this, I can rewrite my Repository’s SQL construction code to this:

Neat.

I’m just starting to use Java8’s functional API and Jooq and being able to write my code this way really helps me to make it more readable, concise and maintainable. I also want to extend this idea to other SQL parts as join and group by blocks that also depend of the user’s crazy combinations from the UI.

» Leer más, comentarios, etc...

Koalite

Equipos tolerantes a fallos

October 27, 2014 05:06 AM

Hace unos años (no tantos) era relativamente raro que al desarrollar una aplicación se prestara mucha atención a aspectos como la tolerancia a fallos, la escalabilidad, etc. Es cierto que había aplicaciones que sí requerían de estas características, pero la gran mayoría de aplicaciones que se desarrollaban acababan instaladas dentro de las empresas, con un sólo servidor y, bueno, de aquella manera.

Hoy en día, con la llegada de la nube (el cloud computing que dirían los que te la quieren vender), parece que la tolerancia a fallos, la escalabilidad y demás son características fundamentales y críticas para cualquier aplicación, incluso para la web de la mercería de la esquina, y todo el mundo está muy familiarizado y concienciado con estos conceptos.

Ahora que todos tenemos claro que es fundamental que los sistemas de los demás tengan esa solidez y robustez, llega el momento de pensar un poco en nosotros, ¿cómo de tolerante a fallos y escalable es tu equipo de desarrollo?

El problema son los humanos

Al hablar de fallos de un equipo de desarrollo podemos pensar en mil tipos de contratiempos, pero en este caso me quiero centrar en el aspecto humano, porque por mucho que les pese a algunos, un equipo de desarrollo no está formado por recursos, sino por humanos, y los humanos son problemáticos de manejar. Además, me gustaría centrarme en factores internos al equipo, asumiendo un mundo de fantasía en el que el entorno ayuda al equipo de desarrollo en su trabajo.

¿Qué pasa si mañana desaparece uno de los miembros del equipo? ¿Y si es “el que sabe” (llámalo líder técnico, arquitecto o lo que más te guste)? ¿Y si desaparece más de uno? ¿Cuál es el factor autobús de tu equipo?

Esto es algo que puede pasar en cualquier momento. No se trata de que lo abduzcan, pero puede cambiar de trabajo, mudarse a otra ciudad, tocarle la lotería o simplemente hartarse. Esto acabará ocurriendo antes o después y debemos estar preparados para ello.

Un problema muy frecuente ante este tipo de situaciones es que, de repente, ya nadie sabe cómo mantener y modificar el código que manejaba esa persona. Eso hace que “su parte” del sistema se vaya degradando poco a poco porque nadie se atreve a meterle mano, los bugs se acumulan y llega un momento en que la situación estalla.

Redundancia y balanceo de carga

La forma más directa de evitar esto es evitar que nadie posea “su parte” del sistema. En terminología de eXtreme Programming, esto sería fomentar la propiedad colectiva del código y hacer que todo el mundo toque (o sea capaz de tocar) todo el código.

Si el proyecto es muy grande, es imposible que todo el mundo toque todo el código, pero debemos intentar que siempre haya más de una persona que pueda modificar cada parte. Si aplicamos técnicas como la programación por parejas o las revisiones de código tendremos mucho ganado, porque todo el código lo habrán visto al menos dos personas.

Hay que tener en cuenta que esto es aplicable a todo lo que comprende el sistema, no sólo el código en C# (o Java), sino también el HTML, el CSS, la base de datos, los scripts de instalación, el script de compilación, etc.

Tener un experto nivel 50 en CSS y que nadie más sepa centrar un div lo que hace es introducir un punto único de fallo en el sistema, es decir, en el equipo de desarrollo, y si la persona que desaparece del equipo es el experto en CSS, tendremos un problema bastante serio.

Una ventaja adicional de emplear este solapamiento de roles es que nos permite balancear la carga entre todos los miembros del equipo. Si cada miembro del equipo es experto en una cosa, podemos tener situaciones en que haya personas que están colapsadas de trabajo mientras otras no tienen nada que hacer porque no se está tocando su área de experiencia. Por el contrario, si todos los miembros del equipo son flexibles, siempre podrán echar una mano en las áreas de la aplicación que así lo requieran en cada momento.

Existe otro enfoque para este problema, que es el de commoditizar a los desarrolladores, asumiendo que no tienen valor intrínseco y que lo único que necesitas cuando se marche un desarrollador es contratar a otro y ya está. Aunque este enfoque tan típico en determinados círculos cárnicos pueda resultar rentable económicamente, técnicamente no suele funcionar muy bien.

Independientemente de lo bueno o malo que sea el desarrollador que estamos reemplazando, si lleva algún tiempo en el equipo habrá adquirido una serie de conocimientos sobre la aplicación y los habrá plasmado en su código, mientras que alguien que parta de cero deberá empezar por adquirir esos conocimientos.

Si además la persona que se está reemplazando no era muy bueno técnicamente o no comprendía bien lo que estaba implementando, seguramente su código y su diseño sean más complicados de entender para quien lo sustituye, entrando en una especie de círculo vicioso que acaba produciendo un código… como el que se suele ver en proyectos gestionados así.

Documentar o automatizar

En realidad, si profundizamos un poco en el problema podemos llegar a la conclusión de que el mayor inconveniente no es que falten una o más personas, sino que hemos perdido el conocimiento que tenían esas personas.

Ya hemos visto que lo ideal es evitar ese punto de único de fallo, pero si no podemos permitírnoslo, una alternativa es el uso de documentación para facilitar la transmisión de conocimiento cuando un miembro deja el equipo.

El problema que tiene la documentación es que es costosa de generar y aún más costosa de mantener. Antes era frecuente encontrarse con documentos de análisis y de diseño llenos de diagramas UML y detalladas descripciones de casos de uso, pero esos documentos tendían a quedarse desactualizados muy rápidamente y acaban por no ajustarse al código real de la aplicación (si es que lo habían hecho alguna vez). Eso hacía que en lugar de ayudarnos a comprender el sistema, nos confundieran aún más.

Una solución a esto es contar con documentación ejecutable, es decir, tests automatizados, que sirvan a la vez para documentar el sistema y para darnos cierta confianza a la hora de introducir partes del sistema con las que no estamos muy familiarizados.

Esto no sólo es aplicable al código como tal, sino también a los procesos que hay alrededor, como la generación de la documentación, de los instaladores, el paso a producción, etc. Si todos esos procesos están automatizados, aunque perdamos al “experto en despliegues” podremos poner una versión en producción ejecutando un simple script. Al final tendremos que comprender cómo funciona ese script para poder mantenerlo, pero al menos habremos ganado tiempo.

Conclusiones

Igual que una aplicación puede estar diseñada para que resista mejor los contratiempos, un equipo de desarrollo puede tomar medidas que le permitan sobrevivir a momentos complicados.

Aplicando conceptos similares a los que usados al diseñar una aplicación podemos analizar cuáles son los factores de riesgo, detectar los puntos únicos de fallo y tratar de buscar medidas que nos permitan limitarlos.

Documentar todo lo que hacemos puede resultar de ayuda para transmitir el conocimiento cuando un miembro deja el equipo, pero el coste de mantener esa documentación es tan algo que pocas veces merece la pena, por lo que tratar de automatizar en lugar de documentar es una buena salida.

Hasta ahora nos hemos centrado en la parte de supervivencia, pero hay otro factor que podemos asimilar entre aplicaciones y equipos de desarrollo: la escalabilidad y cómo podemos preparar un equipo para crecer, pero eso lo dejaremos para un próximo post.

No hay posts relacionados.

» Leer más, comentarios, etc...

carlosrovira.com

Rediseño del Blog

October 26, 2014 05:49 PM

Después de casi 11 años online y varios “lavados de cara”, os presento el último rediseño de este blog. Ahora responsivo (ya sabéis, en casa de herrero…) y trasladado en su totalidad a la raíz del dominio.

Ya sabeis que la temática de este blog está muy ligada al mundo Flash, Flex, Java, pero últimamente me apetece, si el tiempo, la familia, los niños, la empresa y las demás obligaciones lo permiten, hablar de otros muchos temas.

Como siempre con la mejor de las intenciones…lo intentaremos.

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

Structure of BA Documents

October 26, 2014 02:51 AM

http://www.batimes.com/articles/the-structure-of-business-analysis-documents.html

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

Nadella and Microsoft Dynamics CRM

October 26, 2014 02:12 AM

Microsoft CEO Relying on Dynamics CRM to Lead Company on New Journey http://community.dynamics.com/crm/b/crmsoftwareblog/archive/2014/10/24/microsoft-ceo-relying-on-dynamics-crm-to-lead-company-on-new-journey.aspx

» Leer más, comentarios, etc...

El blog de Adrián Arroyo

Esqueleto de juegos NPM

October 26, 2014 12:00 AM

Quería haber empezado este mes con el desafío One Game a Month pero mis herramientas no estaban listas tal y como recomendaba el libro The Game Jam Survival Guide de Christer Kaitila. Así que este mes lo dediqué a hacer herramientas para las juegos. Concretamente he desarrollado dos sets de herramientas (esqueletos a partir de ahora). Uno es de JavaScript/TypeScript y el otro de C++. Quería haber hecho uno de Rust, pero hasta que no salga la 1.0 y lo pueda probar en Windows en condiciones no habrá esqueleto de Rust. Así pues hecha la introducción, en este post voy a hablar del esqueleto de JavaScript/TypeScript que es el que hice primero.

Descripción del esqueleto

El esqueleto ha sido diseñado alrededor de Grunt para su fácil manejo. Me encanta ver como Grunt puede con todo lo que le echen y más (lo único que le falta es un plugin nativo de C++ al estilo de Gradle). Actualmente el esqueleto usa TypeScript para el código. Este maneja las definiciones con TSD, se compila y finalmente se le pasa por Browserify para convertirlo en un único fichero. A parte no hay ficheros HTML, sino que son plantillas Jade; la razón no es muy clara pero prefería tener Jade antes que HTML básico. Quizá me sentía inspirado y pensé que le daba un toque más node.js. Y el CSS tampoco se usa directamente, sino que debemos pasar por el compilador de LESS (aquí la ventaja es más clara que con Jade/HTML). Adicionalmente podemos generar documentación si estuviese documentado el código con TypeDoc y generamos una página del manual de UNIX con markedman. Posteriormente en etapas finales del juego podemos generar iconos de todos los tamaños imaginables (Apple iOS iPhone sin retina, con retina, iPad, iPad mini,… incluso para el navegador Coast). Además se minifican las imágenes con OptiPNG y sus equivalentes para JPG y GIF. Para acabar se añade una tag al repositorio Git y se publica en el repositorio, pero en el branch gh-pages. También he diseñado otra ruta para el empaquetamiento en local de la aplicación. Usando NodeWebkit y un plugin para hacer un paquete Debian (tengo pendiente el RPM) y comprimiendo el resultado en un ZIP listo para el Firefox Marketplace. Además, sin estar automatizados hay código para Ubuntu Touch, Android y Chrome OS.

¿Cómo se usa?

Buena pregunta. Primero debemos clonar el repositorio Git y tenemos que tener en cuenta que a partir de ahora podemos modificar todo con fin de que se adapte a nuestras necesidades. Entonces clonamos con:

git clone https://github.com/AdrianArroyoCalle/skeleton-npm-game TU_JUEGO

Ahora debemos instalar las dependencias. Te recomiendo que vayas a por un café o algo ya que el sistema de dependencias empotradas de NPM hace que el tamaño de la descarga se nos vaya de las manos con ciertas dependencias duplicadas y reduplicadas. Así que entra en la carpeta creada llamada TU_JUEGO y pon:

npm install

Adicionalmente si no tienes Grunt instalado, instálalo con:

npm -g grunt-cli

Es posible que según tu configuración lo debas ejecutar como root o no.
Una vez descargado solo nos quedaría empezar el desarrollo. Podemos hacer una pequeña prueba de que todo se haya instalado con:

grunt test

Librerías incluidas

He incluido las siguientes librarías y me gustaría añadir unas cuantas más pronto:

  • BABYLON.JS
  • three.js
  • GameJS
  • Box2d.js
  • Cannon
  • meSpeak
  • Bongo.js
  • Hammer.js
  • Canvace
  • i18next

Y sin duda me gustaría añadir alguna más, pero con estas creo que se pueden dar muchas combinaciones.

Y una cosa más…

He intentado recopilar la mayor cantidad de sitios donde publicar los juego una vez terminados. La lista ya es bastante grande pero no están probados todas las empresas allí expuestas. Además hay que tener ciudado ya que hay tiendas que son incompatibles entre ellas.

» Leer más, comentarios, etc...

proyectos Ágiles

¡Ya tenemos programa de la Conferencia Agile Spain 2014!

October 25, 2014 06:05 PM

 

¡¡¡ Ya se ha publicado el programa de la CAS2014 !!!

 

La Conferencia anual de Agile Spain nos permitirá conocer experiencias de empresas muy interesantes, oir a ponentes que nos harán pensar de manera diferente y aprender cosas nuevas muy útiles para nuestros proyectos y productos.

CAS2014-the_nex_management

 

Este año la CAS está más enfocada en el Management, ya que es un factor crítico en la transición hacia un modelo Agile y por eso se ha dividido en los siguientes tracks:

 - Enterprise Agile - Para conocer experiencias de empresas más bien grandes, en la adopción de Agile y en el trabajo a gran escala siguiendo principios Agile y Lean.

 - Agile Management - Ideas diferentes para mánagers que trabajan siguiendo este paradigma.

 - Collaboration, culture & teams - Sobre el cambio de modelo mental y creación de equipos.

 - Agile 101 - Para neófitos.

 - Agile + - Para los que quieren conocer cosas avanzadas o diferentes sobre Agile.

 - Dev Practices & craftmanship - Para los desarrolladores de software.

 - Delighting products - Para los que quieren lanzar productos (o mejorarlos) y equivocarse menos.

 

Además, la CAS2014 contará con unos Keynotes de excepción, entre los que se encuentra Jurgen Appelo (autor del libro Management 3.0) y Bjarte Bogsnes (de la línea de pensamiento Beyond Budgeting).

Promete ser una conferencia estupenda, con una aforo con capacidad para 700 personas !!!

Más detalles en la web de la conferencia: http://cas2014.agile-spain.org/

Nos vemos en la CAS ;)

» Leer más, comentarios, etc...

xailer.info

¡Migrar a SQL ya!

October 22, 2014 04:40 PM

Estimados usuarios de Xailer,

Espero que con el título de este artículo haya conseguido llamaros la atención ;-) El motivo del mismo es debido a que a pesar del gran esfuerzo que hemos realizado para dar soporte a otros motores de bases de datos mucho más potentes que nuestros obsoletos DBF, seguimos observando que la mayoría de vosotros seguís anclados en los DBFs.  A pesar de que alguno le parezca una burrada lo que voy a decir, yo personalmente comparo el sistema de archivos DBF con la máquina escribir. Funcionar, funcionan, pero donde esté el más simple tratamiento de textos que se quite cualquier máquina de escribir. Las máquinas de escribir son máquinas del pasado y están bien en una almoneda, pero poco más.  Me temo que los DBFs ni siquiera tienen sitio en alguna parte.  Soy un enamorado del lenguaje xBase, pero me temo que su sistema nativo de archivos está muy superado.

Queremos que cuanto antes todos los desarrolladores de Xailer empiecen a usar motores SQL y abandonen los DBFs definitivamente. Para ello hemos mejorado sustancialmente nuestra herramienta xaSQLite (que podéis descargar desde el enlace) incluyendo opciones para importación másiva de DBFs por directorio a SQLite y exportación completa desde SQLite a MySQL/MariaDB.

Si vuestras aplicaciones van a ser utilizadas únicamente de forma local por uno o dos puestos máximo os recomiendo SQLite sin lugar a dudas. La herramienta xaSQLite os hará la migración desde DBFs a SQLite fácilmente. Una vez realizada la importación es aconsejable modificar la estructura de las tablas para establecer la clave primaria, pero es un proceso muy rápido y sencillo.

Si la base de datos se queda pequeña bien porque va a acoger más puestos, empieza a tener un tamaño considerable o porque queréis un acceso remoto (por ejemplo, desde Internet) os recomiendo el salto a MySQL o MariaDB que desde un punto de vista de programación su uso es idéntico. MariaDB no tiene ningún problema de licencias y  MySQL si. No obstante si  se utiliza nuestra clase TWebDataSource en vez del acceso directo con sus DLL tampoco tendría problemas de licencia. El típico escenario de servicio de hosting por Internet con servidor MySQL y aplicación atacando a dicha base de datos a través de TWebDataSource  no incumpliría ninguna licencia. xaSQLite incorpora una nueva opción para exportar todos sus datos a MySQL/MariaDB de una forma rápida y eficaz. Para ello crea un guión completo con todas las operaciones a realizar de la misma forma que se genera una copia de seguridad de la base de datos.

mysqlexport

Es posible que a más de uno os de pereza aprender SQL, pero pensar que se ideó como lenguaje de consulta para usuarios y no para desarrolladores. Aprender SQL es muy fácil, existen multitud de tutoriales en Internet y además los motores que os estamos indicando en este artículo son completamente gratuitos.  Cuando sepáis SQL os daréis cuenta de que realmente lo complicado son los DBFs y sus índices.

Las ventajas de SQL frente a DBF son tremendas:

  • Robustez
  • Seguridad
  • Escalabilidad
  • Accesibilidad
  • Transacciones atómicas
  • Optimización de ancho de banda
  • Acceso remoto
  • Y muchas más …

Espero haberos convencido alguno para que la próxima aplicación que hagáis utilice un motor SQL o incluso para que esa gran aplicación que tenéis, empecéis a migrarla poco a poco a un entorno SQL.

Un cordial saludo

 

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Sybase Power++

October 22, 2014 01:41 PM

Powersoft lanzó Optima++ en 1996, como un producto estratégico que combinaba el desarrollo RAD de Visual Basic o Delphi, con la potencia de C++, y el compilador líder de aquel tiempo: Watcom C++, es decir, un año antes que Borland hiciera lo propio con el proyecto Ebony que daría lugar a C++ Builder en 1997. En 1997, se renombraría a Power++ (1.0 y 1.5), como influencia de la compra por parte de Sybase en 1995, y en consonancia con PowerBuilder. A partir de ahí vendría la versión 2.0, 2.1 y 2.5 que incluían grandes mejoras, y el nuevo compilador de Watcom C++ 11.0. Con actualizaciones menores, llegaría hasta la versión 2.5 de 1999, muy madura y estable, así como una versión 2.6 que quedó en desarrollo en el 2000 con el anuncio de su abandono. Lo que había empezado siendo una idea única, y combinando virtudes que nadie había conseguido [...]

» Leer más, comentarios, etc...

Variable not found

Inicialización de diccionarios en C# 6

October 21, 2014 11:48 AM

image33En otras ocasiones hemos hablado de novedades que acompañarán a la próxima revisión de C# que nos ahorraban algo de tiempo y pulsaciones de tecla a la hora de codificar algunos escenarios bastante frecuentes, a la vez que mejoraban la legibilidad.

Pues en esa misma línea, vemos ahora una nueva forma de inicializar colecciones clave-valor, como son los diccionarios. Ciertamente es un cambio bastante pequeño, de los que fácilmente podrían pasar desapercibidos junto a otras novedades de mayor peso, pero creo que también vale la pena conocerlo.

Para ponernos en situación, echemos un vistazo al siguiente código, totalmente válido en las versiones actuales de C#:



El código anterior es bastante limpio y pocas pegas se le podría poner, salvo que a primera vista no queda claro en absoluto qué tipo de estructura es CustomColorConverter. Si lo pensamos un poco, veremos que no es sino un Dictionary<string, string>  disfrazado, pero está claro que los elementos con los que lo estamos inicializando no expresan claramente que se trata de una colección de claves y valores. De hecho, a priori una expresión como { "red", "yellow"} pasaría mejor por ser un array o algún tipo de tupla que por ser un diccionario.

Para mejorar la legibilidad en estos escenarios, C# 6 introducirá una sintaxis adicional para la inicialización de este tipo de construcciones. No reduce el número de teclas a pulsar a la hora de escribirlo, pero sin duda deja bastante más claro qué es lo que estamos haciendo:



Ahora sí que salta a la vista que estamos cargando un diccionario, ¿verdad?

Otro ejemplo claro de uso, a menudo citado a la hora de hablar de esta nueva característica, es a la hora de utilizar diccionarios para crear objetos que posteriormente van a ser serializados, por ejemplo, en JSON:



Para finalizar, como curiosidad, decir que hasta hace bien poco se ha mantenido en la lista de características candidatas para C# 6 la introducción del símbolo $ tanto para inicializar diccionarios como para acceder de forma rápida a su contenido con una sintaxis similar a la siguiente:

image

Y salvo la ligera y molesta sensación de estar tocando código PHP, la verdad es que no pintaba mal, pero finalmente ha sido descartada. En principio, este uso del símbolo $ no vendrá la luz en la próxima versión de C#, aunque no se cierra la puerta a que en el futuro se introduzca si existe demanda por parte de la comunidad.

Otros posts de la serie:
Publicado en Variable not found.

» Leer más, comentarios, etc...

Arragonán

Semana 332

October 21, 2014 07:56 AM

La semana pasada resultó bastante agotadora, el lunes era festivo en Aragón y quedó una semana un tanto comprimida con mucho por hacer para recuperar los días no trabajados la semana anterior. Mucho estrés, preocupaciones y descansar bastante mal; os aseguro que cuando empalmas varios días seguidos así te preguntas por qué cojones te pusiste por tu cuenta, por suerte no es lo habitual. Y para rematar, el fin de semana fue de todo menos tranquilo.

Había Rails Rumble y me apunté con Javi, Rafa y Guillermo. Hasta el día de antes no decidimos proyecto, estuvimos hablando de diferentes ideas que teníamos, hasta que comenté uno que me rondaba hace tiempo que podría tener sentido. Una web que te recomendara recetas a partir de los ingredientes que tengas. Y de este hackathon salió leancook.

Leancook

Falta trabajo para afinar las búsquedas, pero no está mal para un fin de semana en el que tampoco es que estuviéramos concentradísimos en ello y nos metiéramos un palizón. Podéis ver un pequeño resumen de la parte técnica en nuestra ficha de equipo, y si queréis votarnos ahí genial :).

Ha vuelto a empezar la temporada en los 2 equipos de fútbol 7 en los que juego los fines de semana. La temporada pasada dije que debería dejar alguno, y además de no haber dejado ninguno, resulta que en el que juego entre semana (fútbol sala) pasamos a los lunes por votación del equipo: 3 partidos en 3 días. Veremos cuanto tardo en reventar.

En cuanto a cuestiones de trabajo:

  • No sin dolor, desplegué en el servidor de producción proyectoSinNombre. Aproveché para actualizar la versión de Refinery y alguna que otra gema. En realidad está desplegada la parte de la que tenemos la conformidad del cliente, tenemos otra parte de la que todavía la tenemos pendiente. Pero al ser partes complementarias, el cliente ya podría hacer público el proyecto una vez cargado de contenidos.
  • Trabajé sobre algunas pequeñas mejoras de mhop que me habían pedido los gestores del contenido.
  • Estuve analizando una web para presupuestar a una startup local un trabajo de web scraping.
  • Tocó trabajar duro en Nort. Seguir trabajando en detalles tanto para la aplicación móvil como para la web, trabajando bastante con el SDK de Facebook para mejorar la integración entre otras cosas. A finales de semana hicimos una demo con el cliente y salió bastante bien.

Buena semana.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 174

October 20, 2014 12:14 PM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada, espero que os resulten interesantes :-)

.Net

ASP.NET

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Formas de organizar el código

October 20, 2014 05:06 AM

Excepto las prácticas de primero de carrera y algunos scripts muy simples, cualquier aplicación acaba constando de un montón de ficheros que necesitamos organizar de alguna manera en carpetas para poder manejarlos sin volvernos locos.

Existen muchas formas de organizar el código y en ellas influye mucho el gusto de cada uno o las convenciones aplicadas por cada equipo de desarrollo, pero eso no quita que también haya formas más o menos estándar, cada una de ellas centrada en mejorar determinados aspectos.

En este post vamos a ver dos filosofías distintas a la hora de organizar el código y veremos qué nos puede aportar cada una.

Organización por roles tecnológicos

La organización por roles es una de las más extendidas actualmente en el desarrollo de software. Probablemente uno de los proyectos que más hizo por este tipo de organización fue Ruby on Rails con su convención sobre configuración basada en la ubicación física en disco de sus modelos, vistas y controladores, y que luego ha sido copiada por otros frameworks como ASP.NET MVC.

Esta organización se basa en agrupar los ficheros en base al rol tecnológico que desempeña en el sistema. De esta forma, si en la capa de presentación estamos aplicando un patrón MVC, tendremos carpetas con Models, Views y Controllers o si tenemos un modelo de dominio estilo DDD, tendremos carpetas con Entities, Repositories, Factories.

Algo parecido a esto:

organización de código por roles

La organización por roles tecnológicos fomenta una forma de pensar homogénea y centrada en aspectos técnicos. Al definir tanto los roles y hacerlos tan explícitos con las carpetas independientes, sirve para remarcar mucho la arquitectura del sistema y eso nos lleva a encajar las nuevas funcionalidades dentro de esa arquitectura.

La principal ventaja de esto es que el diseño del sistema tiende a mantenerse muy homogéneo y la estructura de carpetas actúa como guía al implementar nuevas funcionalidades.

Si quieres montar una nueva funcionalidad para gestionar clientes potenciales en tu aplicación web, te crearás la entidad cliente potencial en la carpeta Entities, el repositorio en la carpeta Repositories, el controlador en Controllers, etc.

Es una buena opción cuando se está trabajando con equipos de desarrollo grandes en los que hay más rotación de personal, porque marca unas pautas muy claras de cómo hacer las cosas y el resultado final resulta más predecible.

Precisamente esta homogeneización se puede convertir en uno de los inconvenientes de esta forma de organizar el código, porque lleva a intentar encajar todas las funcionalidades del sistema en una serie de roles que, a veces, no son necesarios o no son necesariamente la mejor forma de implementar una funcionalidad concreta.

Es algo parecido a lo que ocurre con los diseños de N capas tradicionales, en los cuales puedes acabar creando capas que no aportan ningún valor sólo para mantener el diseño uniforme.

Además, al organizar el código por roles, tendemos a pensar sólo en términos de esos roles. Hay ocasiones en que la mejor forma de implementar algo es utilizando una clase o una función que no encaja en ninguno de los roles, pero como la estructura de carpetas sólo nos habla de controladores, vistas y modelos, acabaremos implementándolo como una de esas cosas. Es frecuente encontrar proyectos en los que todo es un NoSeQuéController, NoSeQuéView o NoSeQuéModel.

Otro problema (menor, si estás usando un IDE moderno con un sistema de navegación potente), es que el código necesario para comprender una funcionalidad queda repartido en muchas carpetas y es difícil saber realmente cuánto código está relacionado con una funcionalidad concreta.

Organización por funcionalidades

La organización por funcionalidades (features) se basa en primar el aspecto funcional sobre el técnico a la hora de decidir dónde colocar cada fichero.

En lugar de agrupar los ficheros por el rol que tienen (Controlador, Repository, ViewModel, Directive…), los agrupamos en base a la funcionalidad que implementan.

Más o menos así:

Organización de código por funcionalidad

Por ejemplo, en una aplicación web MVC que tiene una parte para gestionar clientes podríamos tener una carpeta customers que incluyese el modelo, la vista, el controlador y el resto de cosas que necesitemos.

Llevado al extremo, en cada carpeta tendríamos un slice vertical completo de la aplicación, desde el UI hasta la persistencia, pero normalmente no se llega a tanto, y podemos tener una carpeta customers con el código javascript y html de la nuestra aplicación SPA hecha con angularjs, y en alguna otra parte otra carpeta customers con el código C# de un proyecto WebAPI, con su controlador, servicios para cargar datos, etc.

Si la organización basada en roles tenía cierto parecido con las arquitecturas N capas, podríamos decir que la organización basada en funcionalidades se asemeja más (salvando las enormes distancias) al concepto de microservicios que está tan de moda ahora, porque fomenta el minimizar las dependencias entre unas carpetas y otras para tener funcionalidades lo más cohesivas e independientes posibles.

Esta forma de organizar el código evita los inconvenientes de la organización por roles. Con ella todo el código relativo a una funcionalidad está físicamente cerca, ayudando a saber mejor qué código está ligado a esa funcionalidad y a navegar por él.

Además facilita la navegación por la aplicación a un nivel más alto. Cuando ves carpetas llamadas Customers, Orders o Catalogue, es más fácil hacerse a la idea de qué hace la aplicación que si ves carpetas llamadas Controllers, Views y Models.

A la hora de implementar nuevas funcionalidades ayuda a considerarlas de forma independiente, por lo que resulta más sencillo “separarse” del diseño general y utilizar diseños más optimizados para cada funcionalidad concreta sin necesidad de ajustarnos a unos roles marcados previamente.

Esa libertad para implementar nuevas funcionalidades se convierte en un arma de doble filo si estás trabajando con gente que no es capaz de diseñar con un mínimo de sentido común, puesto que resulta más complicado fomentar el uso de buenas prácticas prácticas estandarizadas de diseño.

Mezclando ambas alternativas

Hasta ahora hemos visto dos formas de organizar el código que parten de ideas distintas y priorizan objetivos diferentes, pero no hace falta ser muy listo para darse cuenta de que en realidad estamos hablando de dos ejes distintos, roles técnicos y funcionalidades, y que en el fondo son dos conceptos ortogonales, por lo que podemos mezclarlos a nuesto antojo.

De hecho, lo normal es que cuando una aplicación se hace realmente compleja (cientos de ficheros) se acaben mezclado de una forma u otra.

Si se ha empezado organizando por roles técnicos, llega un momento en que tener 400 controladores de AngularJS en una sola carpeta se hace inmanejable y se acaba separándolos en distintas carpetas dentro de la carpeta controllers.

Igualmente, si cada funcionalidad de una aplicación con AngularJS acaba teniendo 3 directivas, 2 filtros, 4 controllers y 5 vistas, es razonable que terminemos particionando más los ficheros, ya sea mediante carpetas o alguna convención de nombres en los propios ficheros.

Conclusiones

La manera de organizar el código no sólo influye en dónde colocamos cada fichero, sino que también puede condicionarnos a la hora de diseñar el sistema o de implementar nuevas funcionalidades.

Si priorizamos el aspecto técnico organizando el código por roles, conseguiremos sistemas más homogéneos, con un código más estándarizado entre unas partes y otras de la aplicación, pero también nos puede hacer sentir una pérdida de libertad al implementar nuevas funcionalidades por intentar encajarlas en una estructura preestablecida.

Personalmente, hoy en día prefiero inclinarme hacia el lado de la organización por funcionalidad, incluso aunque luego el 80% de las funcionalidades tengan la misma estructura (y, por tanto, encajarían bien en una organización por roles). Pese a que esto requiere pensar más para decidir cómo implementar cada funcionalidad, a cambio permite pensar con más libertad en la forma de implementarla, y en mi opinión eso merece la pena.

No hay posts relacionados.

» Leer más, comentarios, etc...

Blog Bitix

Qué es y cómo hacer «web scraping» en Java

October 17, 2014 04:00 PM

Java

Algunas aplicaciones en internet necesitan intercambiar información para hacer algún tipo de integración. La tendencia actual es proporcionar una API REST o algún tipo de archivo descargable con cierto formato que permita procesarlo de forma automatizada y a las aplicaciones obtener la información de forma sencilla y precisa. Sin embargo, hay ocasiones en las que las aplicaciones de las que necesitamos extraer la información no proporcionan ni una API REST ni un archivo descargable con lo que no nos queda más remedio que extraer los datos de la propias páginas web inspeccionando el código HTML, esto en inglés se le conoce como «web scraping».

En este artículo explicaré como hacer web «scraping» usando la librería jsoup y usando el lenguaje de programación Java. jsoup proporciona una API para poder extraer la información que necesitemos, ya sean las URLs de los enlaces, determinado texto que contiene una valor, imágenes, … . A través de los selectores similares a los usados en jquery podemos llegar a los elementos que queremos de forma simple sin tener que hacer complicados algoritmos.

Dada la URL, archivo o String con contenido HTML podemos extraer los enlaces de imágenes, enlaces, hojas de estilos, iconos como se muestra en el siguiente ejemplo:

http://jsoup.org/cookbook/extracting-data/example-list-links

Un ejemplo práctico en el que podríamos hacer «scraping» es por ejemplo para extraer los enlaces torrent de descarga de todos los libros de un determinado autor o determinada serie de la página epublibre, esto nos ahorraría tener que hacerlo manualmente. Además si usamos transmission a través de su API podríamos automatizar la descarga.

El algoritmo o algoritmos que necesitemos para extraer la información será específico según la estructura HTML de cada página web, si esta cambia deberemos cambiar el algoritmo o los selectores, en cualquier caso es mejor que tener que hacer la tarea manualmente constantemente que al cabo de un tiempo será tediosa, aburrida y repetitiva.

Pero hay que tener cuidado con el contenido «scrapeado» y se debe tratar como una fuente de datos no segura. Por seguridad hay que tener especial cuidado con los scripts del contenido importado que podrían hacer que nuestra aplicación al mostrarlos tuviese algún problema de seguridad. La siguiente semana explicaré como «scrapear» contenido de forma segura en un ejemplo real como es el agregador de bitácoras Blog Stack donde solo se permiten los scripts de fuentes consideradas seguras como presentaciones de Speakerdeck, Gist de GitHub, YouTube, Vimeo o publicidad del programa de afiliados de Amazon.

Referencia:
Cómo filtrar contenido HTML de forma segura

» Leer más, comentarios, etc...

Blog Bitix

Cómo filtrar contenido HTML de forma segura

October 17, 2014 02:53 PM

Java

Algunos sitios y aplicaciones pueden tener la necesidad de «scrapear» el contenido de sitios web para extraer información de ellos y posteriormente usarla de alguna forma. El contenido «scrapeado» o obtenido de una fuente externa debe ser filtrado, si no es filtrado y posteriormente es servido a los usuarios puede enviárseles principalmente scripts con contenido malicioso (provocando un ataque cross-site scripting, XSS) o causar una desmaquetación al visualizar el contenido. A la hora de implementar la agregación de contenido de forma segura en Blog Stack, contenido obtenido de una fuente RSS o Atom pero que en esencia es HTML he usado la librería jsoup, de tal forma que solo el contenido considerado seguro o confiable de los artículos sea agregado.

¿Que puede pasar si en una fuente envía elementos <script>, <iframe> u <object>? Los <script> son código que se envía al navegador del usuario y que podrían explotar algún fallo de seguridad del navegador que usen, los <iframe> permiten cargar contenido de una tercera fuente. En definitiva podrían hacer que visitar Blog Stack fuese inseguro. Pero no permitir incluir estos elementos también haría que no se pudiesen mostrar vídeos de YouTube, Vimeo, Gist de GitHub, presentaciones de SpeackerDeck y se perdería parte del contenido original. La solución que he aplicado en Blog Stack es permitir el contenido de esos elementos que provienen de una fuente considerada confiable, es decir, si se trata de un iframe cuyo elemento src proviene de YouTube se permite el contenido ya que se supone que YouTube y su contenido es seguro. De esta forma el contenido puede agregarse de forma segura sin perder nada del contenido original.

Para hacer el filtrado de HTML en java podemos usar jsoup, para ello deberemos usar la clase Whitelist que proporciona jsoup o implementar una clase que la extienda con las etiquetas y sus atributos que consideramos seguros. En Blog Stack he necesitado implementar una clase Whitelist agregándole la funcionalidad que deseaba.

Esta es la implementación de la clase Whitelist, con el método addTag se indican los tags permitidos, con addAttributes se indican los atributos permitidos para cada etiqueta, addProtocols se indican los protocolos permitidos para cada etiqueta y atributo, finalmente el método addAttribute permite usar una expresión regular para el valor del atributo, esto se comprueba en el método isSafeAttribute:

<noscript><pre><code>package info.blogstack.misc; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jsoup.nodes.Attribute; import org.jsoup.nodes.Element; import org.jsoup.safety.Whitelist; public class AppWhitelist extends Whitelist { private List&lt;Map&lt;String, String&gt;&gt; attributes; private AppWhitelist() { attributes = new ArrayList&lt;&gt;(); } public static Whitelist relaxed() { Whitelist wl = new AppWhitelist() .addTags(&quot;a&quot;, &quot;b&quot;, &quot;blockquote&quot;, &quot;br&quot;, &quot;caption&quot;, &quot;cite&quot;, &quot;code&quot;, &quot;col&quot;, &quot;colgroup&quot;, &quot;dd&quot;, &quot;div&quot;, &quot;dl&quot;, &quot;dt&quot;, &quot;em&quot;, &quot;h1&quot;, &quot;h2&quot;, &quot;h3&quot;, &quot;h4&quot;, &quot;h5&quot;, &quot;h6&quot;, &quot;i&quot;, &quot;img&quot;, &quot;li&quot;, &quot;ol&quot;, &quot;p&quot;, &quot;pre&quot;, &quot;q&quot;, &quot;small&quot;, &quot;strike&quot;, &quot;strong&quot;, &quot;sub&quot;, &quot;sup&quot;, &quot;table&quot;, &quot;tbody&quot;, &quot;td&quot;, &quot;tfoot&quot;, &quot;th&quot;, &quot;thead&quot;, &quot;tr&quot;, &quot;u&quot;, &quot;ul&quot;) .addAttributes(&quot;a&quot;, &quot;href&quot;, &quot;title&quot;) .addAttributes(&quot;blockquote&quot;, &quot;cite&quot;) .addAttributes(&quot;col&quot;, &quot;span&quot;, &quot;width&quot;) .addAttributes(&quot;colgroup&quot;, &quot;span&quot;, &quot;width&quot;) .addAttributes(&quot;img&quot;, &quot;align&quot;, &quot;alt&quot;, &quot;height&quot;, &quot;src&quot;, &quot;title&quot;, &quot;width&quot;) .addAttributes(&quot;ol&quot;, &quot;start&quot;, &quot;type&quot;) .addAttributes(&quot;q&quot;, &quot;cite&quot;) .addAttributes(&quot;table&quot;, &quot;summary&quot;, &quot;width&quot;) .addAttributes(&quot;td&quot;, &quot;abbr&quot;, &quot;axis&quot;, &quot;colspan&quot;, &quot;rowspan&quot;, &quot;width&quot;) .addAttributes(&quot;th&quot;, &quot;abbr&quot;, &quot;axis&quot;, &quot;colspan&quot;, &quot;rowspan&quot;, &quot;scope&quot;, &quot;width&quot;) .addAttributes(&quot;ul&quot;, &quot;type&quot;) .addProtocols(&quot;a&quot;, &quot;href&quot;, &quot;ftp&quot;, &quot;http&quot;, &quot;https&quot;, &quot;mailto&quot;) .addProtocols(&quot;blockquote&quot;, &quot;cite&quot;, &quot;http&quot;, &quot;https&quot;) .addProtocols(&quot;cite&quot;, &quot;cite&quot;, &quot;http&quot;, &quot;https&quot;) .addProtocols(&quot;img&quot;, &quot;src&quot;, &quot;http&quot;, &quot;https&quot;) .addProtocols(&quot;q&quot;, &quot;cite&quot;, &quot;http&quot;, &quot;https&quot;) // .addTags(&quot;script&quot;, &quot;iframe&quot;, &quot;noscript&quot;) .addAttributes(&quot;div&quot;, &quot;style&quot;) .addAttributes(&quot;img&quot;, &quot;style&quot;) .addAttributes(&quot;script&quot;, &quot;src&quot;, &quot;data-.*&quot;) .addAttributes(&quot;iframe&quot;, &quot;src&quot;, &quot;width&quot;, &quot;height&quot;, &quot;frameborder&quot;, &quot;allowfullscreen&quot;, &quot;style&quot;, &quot;marginwidth&quot;, &quot;marginheight&quot;, &quot;frameborder&quot;, &quot;scrolling&quot;) .addAttributes(&quot;object&quot;, &quot;width&quot;, &quot;height&quot;) .addAttributes(&quot;param&quot;, &quot;name&quot;, &quot;value&quot;) .addAttributes(&quot;embed&quot;, &quot;src&quot;, &quot;type&quot;, &quot;width&quot;, &quot;height&quot;, &quot;allowscriptaccess&quot;, &quot;allowfullscreen&quot;); return wl; } public Whitelist addAttribute(String tag, String key, String regexp) { Map&lt;String, String&gt; attribute = new HashMap&lt;&gt;(); attribute.put(&quot;tag&quot;, tag); attribute.put(&quot;key&quot;, key); attribute.put(&quot;regexp&quot;, regexp); return this; } @Override protected boolean isSafeAttribute(String tagName, Element el, Attribute attr) { for (Map&lt;String, String&gt; attribute : attributes) { String tag = attribute.get(&quot;tag&quot;); String key = attribute.get(&quot;key&quot;); String regexp = attribute.get(&quot;regexp&quot;); if (tag.equals(tagName) &amp;&amp; attr.getKey().matches(key) &amp;&amp; attr.getValue().matches(regexp)) { return true; } } return super.isSafeAttribute(tagName, el, attr); } } </code></pre></noscript>

Y esta es la forma de usar la clase a través de Jsoup.clean:

<noscript><pre><code>AppWhitelist whitelist = (AppWhitelist) AppWhitelist.relaxed(); whitelist.addAttribute(&quot;script&quot;, &quot;src&quot;, &quot;^http[s]?://speakerdeck.com/.*$&quot;); whitelist.addAttribute(&quot;script&quot;, &quot;src&quot;, &quot;^http[s]?://gist.github.com/.*$&quot;); whitelist.addAttribute(&quot;iframe&quot;, &quot;src&quot;, &quot;^http[s]?://www.youtube.com/embed/.*$&quot;); whitelist.addAttribute(&quot;iframe&quot;, &quot;src&quot;, &quot;^http[s]?://player.vimeo.com/video/.*$&quot;); whitelist.addAttribute(&quot;iframe&quot;, &quot;src&quot;, &quot;^http[s]?://rcm-eu.amazon-adsystem.com/.*$&quot;); whitelist.addAttribute(&quot;embed&quot;, &quot;src&quot;, &quot;^http[s]?://www.youtube.com/v/.*$&quot;); String content = Jsoup.clean(postContent.toString(), source.getPageUrl(), whitelist);</code></pre></noscript>

El código fuente completo de BS junto con el «scrapeado» y el uso de esta clase está disponible en un repositorio de GitHub.

Referencia:
Qué es y cómo hacer «web scraping» en Java

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

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.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin