Noticias Weblogs Código

carlosrovira.com

HTML5 lo seguirá intentando en 2014…

April 22, 2014 12:21 PM

Después de leer, una vez más, sobre la posible muerte de Flash a manos de HTML5 (sí, ya se que debéis de estar tan aburridos como yo del tema…) durante este año 2014 (ni antes ni después) en este artículo, me he decidido a responder. Lo cierto es que nada más lejos. HTML5 lo sigue intentando, pero el hype generado se empieza a desinflar y empiezan a salir a la luz todos los problemas. Pero la historia no es nueva, ya se dió hacia 2004-2005, y ahora la volvemos a repetir…

Reproduzco aquí el comentario ya que al final es largo y me parece de interés para hacer una entrada de blog:

Mi lectura es muy distinta, en los últimos meses el hype generado por HTML5 se empieza a desinflar por muchas razones. Además muchas compañías de relevancia en Internet han terminado abandonando HTML5 y se están volcando en el el desarrollo de Apps nativas. Algunos ejemplos son: Facebook, LinkedIn…o la más reciente The Washinton Post. Algunos usan Adobe AIR como tecnología para desarrollar a la vez para iOS, Android, etc… y Adobe AIR usa internamente Adobe Flash Player.

Lo cierto es que los que trabajamos día a día con tecnologías cliente ya lo decíamos. HTML5 no ha supuesto un cambio radical sobre HTML y los problemas que teníamos en el año 2000, los seguíamos teniendo en 2010 y también ahora en 2014. El motivo es claro, HTML está orientado al *documento*, al *texto*, y no es la mejor solución para crear una *aplicación*, y esto sigue siendo así en 2014, pues la tecnología no ha cambiado sustancialmente desde entonces.

Además seguimos teniendo los grandes problemas inherentes de siempre que la hacen inviable a futuro:

  • Fragmentación: La cantidad de proveedores de navegadores aumentan y hace que las aplicaciones no funcionen de forma directa por igual en cada implementación. Los problemas son diversos, fallos en la visualización de la pantalla, en la interacción con la misma, etc… Este es uno de los grandes problemas que se seguirá acentuando por que no hay un organismo o fundación que unifique los motores que implementan los distintos navegadores. Al revés, cada vez se generan más discrepancias y en vez de acuerdos, conseguimos más “clones” que difieren en diferentes aspectos.
  • Rendimiento y Lentitud: Aunque el aumento de la velocidad de Javascript ha sido impresionante, sigue siendo más lento y rinde peor que una solución nativa del dispositivo o una solución Flash. Esto es normal por la naturaleza del la tecnología cuya razón de ser es mostrar texto e imágenes y no crear aplicaciones que procesen gráficos o complejos algoritmos.
  • Desarrollo inconsistente: La naturaleza de Javascript como lenguaje “no tipado” hace que desarrollar en esta tecnología no sea productivo y sus costes se disparen (algo que muchas empresas están ahora notando en su propio bolsillo y es uno de los grandes motivos para que la burbuja se esté desinflando). El tipado en los lenguajes es la forma de identificar que los datos son de un cierto tipo o clase. Gracias a esto podemos depurar código en tiempo de ejecución y mejorar el software. Javascript no tiene nada de esto, y es uno de los grandes problemas por los que es imposible plantear grandes proyectos que puedan crecer en funcionalidad y lineas de código, como pasaría en otros lenguajes como Java o ActionScript. Como en todo se han creado ciertas formas de emular esto, pero nuevamente sin un cambio de la tecnología, no dejan de ser intentos de evitar un problema monumental que no tiene solución hoy por hoy.
  • Video: HTML5 sigue en 2014 sin ofrecer una experiencia de video en streaming consistente, así como los problemas para ofrecer acceso al micrófono, cámara o tener DRM.

Estos son los 4 problemas más importantes, pero la realidad del desarrollo para HTML5 es más compleja que todo esto.

En resumen. HTML5 es una tecnología correcta y la mejor para el desarrollo de web sites donde el texto y las imágenes son la principal razón de ser. En cambio es un camino erróneo para el desarrollo de aplicaciones por que no fue una tecnología creada con ese objetivo y nunca ha evolucionado para que sea así. Tampoco hemos visto pasos decisivos en estos 4 años para que podamos augurar que esta tendencia cambiara en los próximos meses o años.

Steve Jobs, o Erika Trautman, aunque grandes profesionales en su ámbito, no son expertos ni prescriptores en la tecnología, y por tanto no deberían ser ellos quienes guiasen con sus comentarios mediaticos hacia donde debe ir este mundo en concreto.

Por cierto, que hay grandes novedades en Adobe AIR y Adobe Flash Player para este año 2014, lo que merece una entrada a parte. Parece que Adobe empieza a despertar de su letargo y ha entender que tiene una tecnología que sigue siendo hoy en día imbatible.

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

Poesía Binaria

Singletons en C++. Intentando que sean seguros en hilos (thread safety) II

April 22, 2014 08:50 AM

Singleton thread-safeAyer hablábamos de la creación de un sigleton y de que nuestro ejemplo no era “thread safe”, vamos, que en un entorno con varios hilos de ejecución cabe la posibilidad de que el comportamiento esperado no siempre se cumpla.

Ahí encontrábamos diferencias entre C++ (<11) y C++11 ya que esta última revisión incluye tratamiento de threads y algunas cosas más que trataremos aquí.

Lo primero que podemos pensar, es que al traernos la instancia de nuestro singleton se crea una sección crítica, la cuál podemos regular con un mutex, provocando que siempre que vayamos a obtener una instancia de nuestro objeto pasemos por el semáforo, y aunque dos threads quieran pelearse por ver quién crea antes el recurso, sólo uno lo conseguirá finalmente.… Leer artículo completo

La entrada Singletons en C++. Intentando que sean seguros en hilos (thread safety) II aparece primero en Poesía Binaria.

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

Koalite

Por qué sigo usando un ORM

April 22, 2014 04:06 AM

En el mundo del desarrollo de software, como en todas partes, las modas van y vienen. Cuando hace unos años (ya bastantes) surgieron los ORMs, con Hibernate para Java a la cabeza, se generó bastante discusión sobre si eran una solución adecuada al problema de la persistencia, con opiniones para todos los gustos y argumentos válidos tanto a favor como en contra.

Por una parte, estaban aquellos que consideraban que ceder el control del acceso a la base de datos a una librería daba lugar a soluciones subóptimas, con consultas SQL pesadas y patrones de acceso no recomendables.

Enfrente, había quienes llegaban a decir que no usar un ORM y escribir consultas las consultas a mano suponía robar a tus clientes porque implicaba dedicar tiempo a resolver un problema ya resuelto en lugar de centrarse en aportar valor.

Con el paso del tiempo, los ORMs ganaron la batalla y se convirtieron en mainstream. En el caso de .NET un factor clave para ello fue la aparición de Entity Framework, apadrinado por Microsoft, que hizo que la barrera de entrada a este tipo de herramientas fuese mucho más baja y hoy en día sea el estándar de facto para acceso a datos en .NET.

En paralelo, la necesidad de hacer aplicaciones con un rendimiento cada vez mayor fue haciendo que se volviesen a tener en cuenta los problemas asociados a las abstracciones introducidas por un ORM y se desarrollasen alternativas más ligeras, los MicroORMs, que permitían un acceso más explícito y controlado a la base de datos.

Si a eso le unimos el auge de las bases de datos NoSQL, especialmente de las bases de datos documentales del estilo de MondoDB o RavenDB, capaces de almacenar directamente grafos de objetos sin necesidad de hacer una traducción entre el modelo de objetos y el modelo de persistencia, hoy en día los ORMs vuelven a parecer una solución innecesaria, que sólo introduce complejidad y que penaliza el rendimiento de la aplicación.

Sin embargo, y pese a todos los argumentos en contra, a día de hoy sigo utilizando un ORM (NHibernate) en muchos de mis desarrollos. ¿Por qué?

¿Qué aporta un ORM?

A priori, un ORM se encarga de guardar y cargar información de una base de datos relacional de manera automática. Esto quiere decir que nos evita tener que escribir a mano las consultas SQL necesarias para persistir y recuperar nuestro modelo de objetos, y para muchos, este es el único motivo para utilizar un ORM.

Pero un ORM aporta otras cosas que, por mi forma de trabajar, son mucho más importantes que el evitar escribir sentencias SQL a mano.

Un ORM nos garantiza a través del identity map que siempre que cargamos una misma entidad en una sesión, ya sea a través de distintas consultas o navegando relaciones diferentes, obtengamos una referencia al mismo objeto.

Realizar manualmente esta gestión es complicado y podemos acabar teniendo en memoria dos instancias distintas para representar una misma entidad, cada una con valores diferentes, dando lugar a errores y obligándonos a tener mucho cuidado con la forma y lugar en que cargamos los datos.

Además, el ORM se encarga de gestionar la unidad de trabajo (Unit of Work) con la que podemos interactuar explícitamente (Save, Delete) pero también, y lo que es más importante, de forma implícita mediante la detección automática de cambios y la persistencia por alcance.

Esto nos permite trabajar cómodamente el modelo de objetos en memoria sin tener que llevar la cuenta manualmente de aquello que hemos modificado, ya que el ORM se encargará de detectarlo automáticamente y realizar las operaciones necesarias en la base de datos para persistir los cambios.

Un último punto que me resulta especialmente útil es poder centralizar en el ORM la definición del esquema de base de datos. Con ello conseguimos acercarnos al ideal de tener una única fuente de verdad de la que parte todo el conocimiento sobre nuestro modelo.

En lugar de mantener por separado un esquema de datos y por otro un modelo de objetos, el esquema de datos “emana” del modelo de objetos, facilitando que ambos se mantengan sincronizados.

Una ventaja adicional de esto es que es muy sencillo automatizar la creación y actualización de la base de datos, lo que es facilita mucho las cosas no sólo para el despliegue de la aplicación, sino también durante el desarrollo o los tests.

¿Cuál es el problema con los ORMs?

Todo lo anterior no es gratis y hay que ser consciente del precio que se está pagando por usar un ORM.

El primer problema, y al que más veces se hace referencia, es la pérdida de rendimiento, especialmente a la hora de cargar información. En realidad, muchas veces esta es una cuestión más de cómo se use el ORM que del ORM como tal. Todos los ORMs decentes que conozco permiten utilizar distintos sistemas de lectura, algunos de ellos tan optimizados cuyo rendimiento es indistinguible de lanza las consultas a mano.

Otro problema recurrente es la complejidad adicional que introducen y que, en muchos casos, resulta innecesaria. A fin de cuentas, escribir un par de selects y de inserts no es tanto trabajo, y tener que incluir una librería tan pesada como es un ORM para ello no parece que merezca la pena.

Pero el problema real con los ORMs es que se usan en aplicaciones sin un modelo de objetos. Un ORM, por definición, está diseñado para resolver un problema concreto, el mapeo entre un modelo relacional y un modelo de objetos, y hay muchas aplicaciones que no tienen (y probablemente no necesitan) un modelo de objetos.

Si tu modelo de “objetos” es un fiel reflejo de tu esquema de base de datos, con objetos que prácticamente sólo contienen datos sin operaciones asociadas, donde cada clase se corresponde exactamente con una tabla y los tipos de datos de las propiedades de esas clases son calcados a los tipos de datos de las columnas de las tablas, utilizar un ORM seguramente no sea la mejor solución y puedas obtener resultados muchos mejores con otro tipo de herramientas.

Esto no es algo malo, hay muchas aplicaciones que realmente no necesitan nada más y eso no las hace peores, ni necesariamente más simples. Muchas veces la complejidad de una aplicación no reside en un modelo con operaciones complicadas sino en ofrecer, por ejemplo, una excelente experiencia de usuario o manejar un volumen de datos enorme.

¿Por qué sigo usando un ORM?

El motivo por que sigo usando un ORM es porque, actualmente, la manera en que diseño la mayoría de las aplicaciones con las que trabajo es utilizando un modelo de objetos, y eso hace que todas las cosas que aporta un ORM y que mencionaba antes sean importantes para mi forma de trabajar.

Utilizar un ORM me permite centrarme en diseñar mi modelo de objetos sin tener que pensar demasiado en la forma en que lo persistiré y organizar toda mi aplicación alrededor de ese modelo de objetos. Para mi eso es un valor importante.

En realidad, esto nos llevaría a escalar la pregunta, ¿por qué diseñar una aplicación alrededor de un modelo de objetos?, pero esa es una pregunta diferente que depende de muchos factores, entre ellos el tipo de aplicaciones a desarrollar, el equipo de desarrollo, etc.

En mi opinión, una de las razones por las cuales los ORMs están empezando a tener “mala fama” en el mundo de .NET es Entity Framework. La excelente documentación que tiene y su facilidad de uso se ha convertido en un arma de doble filo que ha hecho que se adopte en muchos proyectos en los cuales no es necesario utilizar un ORM. Si a eso le unimos las carencias que todavía tiene a la hora de mapear modelos complejos (ausencia de tipos personalizados, imposibilidad de mapear objetos inmutables, falta de herencia implícita, etc.), hace que se acabe viendo el ORM como un DataMapper avanzado, cuando un ORM es mucho más que eso.

No hay posts relacionados.

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

Poesía Binaria

Singletons en C++ y alguna nota sobre thread safety (I)

April 21, 2014 08:57 AM

Antes de nada, comentar que he dividido este post en dos porque vi que se estaba alargando demasiado y se lanzarán uno al día, pondré aquí enlaces a todos los posts.

Muchas veces cuando estamos programando tenemos la necesidad de crear un objeto de una clase determinada, pero éste objeto deberá ser creado una sola vez en nuestra aplicación y debemos evitar a toda costa que pueda ser creado más veces.… Leer artículo completo

La entrada Singletons en C++ y alguna nota sobre thread safety (I) aparece primero en Poesía Binaria.

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

Made In Flex

BlackBerry dejará de dar soporte a Adobe AIR a nivel de SO

April 17, 2014 12:39 AM

BlackBerry dejará de dar soporte para Adobe AIR en la versión 10 a nivel de SO.…

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

Made In Flex

Desarrollo Flex para iOS

April 16, 2014 11:40 PM

Con Flex y Adobe AIR podemos desarrollar para la gran mayoría de plataformas disponibles hoy en día, tales como iOS, Android, Mac, Windows o cualquier navegador. No obstante, vamos a centrar este artículo en el desarrollo para iOS…

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

Made In Flex

vSphere Web Client SDK for vSphere 5.1 y 5.5

April 15, 2014 08:43 AM

Desde hace unas versiones VMware paso su cliente de java a Flex de hecho las nuevas funciones y sistemas solo son modificables con su versión web por ejemplo modificar una VM de la versión 10 no es…

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

Navegapolis

Ética empresarial

April 14, 2014 08:20 PM

ÉticaLa "ética empresarial" es cuestionable cuando se antepone el beneficio propio al del cliente.

Para medir la ética de mis comportamientos no tengo que mirar los beneficios que me producen, sino los que producen en los demás.

La ética empresarial no se muestra con palabras, sino con los beneficios que la actividad de la empresa genera en los demás. La ética es esencialmente altruista, y las empresas éticas deberían responder más a motivaciones altruistas que egoístas.

En una empresa ética el beneficio propio es una consecuencia de su actuación para garantizar la continuidad de su trabajo, pero no es su fin. Su fin es el beneficio de sus clientes, trabajadores y la sociedad en general.

Quizá un criterio para determinar el nivel ético de la empresa pudiera ser saldo "green" y "commons" que produce esa empresa en el sistema: si es positivo o negativo y en qué proporción.

Post relacionado: ¿Cuál es la finalidad de las empresas?

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

Picando Código

aprend.io – Aprende Front-End de forma gratuita y en Español con videos

April 14, 2014 02:36 PM

aprend.ioSi están con ganas de empezar a aprender HTML y CSS, o conocen a alguien en esa situación, esto les va a interesar.

La semana pasada se lanzó el proyecto aprend.io: un sitio compuesto por 16 videos acompañados de código para empezar a aprender los fundamentos de Front–End Development.

Los videos están divididos en 3 temas principales: HTML, CSS y un proyecto de ejemplo; Pizzatio. Viendo los videos en orden y practicando con ayuda del código de ejemplo podrás llegar a tener una comprensión firme de lo fundamental de Front–End Development.

aprend.io

aprend.io

DrummerHead es el anfitrión del curso y te lleva de la mano con los videos y ejemplos de código, pero depende también del esfuerzo que cada uno le ponga arriba para seguir aprendiendo.

Genial tener recursos de aprendizaje nuevos, en español, libres y gratuitos. Todo el código de ejemplo esta bajo los términos de la Licencia MIT, el código que compone aprend.io también esta bajo los términos de la Licencia MIT. Los videos están bajo los términos de la licencia Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International

Los invito a visitar aprend.io y que vean de qué va la cosa.

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

Arragonán

Semana 305

April 14, 2014 12:53 PM

Bastante variada la semana que acaba de pasar, desde una visita relámpago por mi pueblo hasta ejercer de facilitador en el hackathon Space Apps Challenge celebrado en Zaragoza, pasando por impartir una charla en el Betabeers Zaragoza o quedarme colgado en mitad de una portabilidad de proveedor de ADSL en mi casa.

Quedarme sin ADSL a mitad de semana ha trastocado mis rutinas. Aún pudiendo ir tirando de tethering para algunas cosas, ha provocado que pase más horas en el estudio de lo que para mi es habitual. A ver si esta semana se hace efectiva mi portabilidad y vuelvo a mi “normalidad”.

Dediqué bastante tiempo en preparar mi charla A falta de APIs buenas son tortas para la edición especial de Betabeers Zaragoza, a modo de introducción al web scraping.

Aunque tenía claro en mi cabeza qué es lo que quería contar, a mi siempre me cuesta mucho definir cómo hacerlo y además intentar que sea lo más ameno posible. Al ser una edición especial me había hecho a la idea de que apenas pasaría de la veintena de asistentes, pero resultó que estaba bastante equivocado, menudo susto XD.

Ya durante el finde, ejercí de “facilitador” del Space Apps Challenge, era el primer hackathon en el que asumía un rol diferente al de participante. A nivel técnico no es que hiciera gran cosa, echar una mano en momentos puntuales de atasco en un par de equipos, lo demás fue ayudar a la organización en algunas cosillas y andar dando apoyo moral a los participantes.

Además de ver lo mucho que se lo curraron los equipos y los resultados del hackathon, me gustó ver que hay cantera; había un buen puñado de jóvenes participando muchos de ellos aún estudiando. Por poner un par de peros, eché de menos que hubieran más variedad de perfiles, especialmente encontré mucho a faltar la presencia diseñadores; y cómo no, que más chicas se hubieran animado a participar tal y como lo hizo Sandra.

Y lo que en mis proyectos se refiere, la semana fue algo así:

  • Tras un par de pequeños arreglos en mhop, empecé a dedicarme a implementar el alta de productos por parte de los diseñadores. Ahora mismo sólo pueden hacerlo los administradores y se consume mucho esfuerzo en la comunicación con los diseñadores industriales.
  • Tuvimos una reunión de proyectoSinNombre de la que surgieron detalles que cerrar, y a ello le dedicamos algunas horas semana.
  • Prepararé y envié una propuesta para un proyecto relacionado con eventos y ticketing.
  • Recopilé las facturas para el IVA trimestral.
  • Hice algunas tareas de mantenimiento minchador.

Buena semana.

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

Variable not found

Enlaces interesantes 154

April 14, 2014 11:58 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes ;-)

.Net

Asp.net

Data access

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Publicado en Variable not found

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

Made In Flex

FlexUnit 4.2.0 es ahora parte de Apache Flex

April 14, 2014 10:39 AM

En las últimas semanas se ha estado preparando la donación de FlexUnit al proyecto Apache Flex. Una vez realizado el trabajo y las adaptaciones necesarias, se ha realizado la votación de rigor y ya podemos decir que…

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

Una sinfonía en C#

Backbonejs: Rutas

April 13, 2014 01:37 PM

Dijimos que Backbone es especialmente útil para aplicaciones SPA (single page applications) así que vamos a ver un componente que nos ayuda con este tipo de aplicaciones.

¿Qué es una SPA?

Son aplicaciones que transcurren en la misma página, sin ir de una página a otra, un ejemplo típico de Gmail, cuando estamos en la bandeja de entrada vemos un listado de mails, hacemos click en uno de ellos y seguimos en la misma página pero si mirando con atención vamos a notar que parte de la URL ha cambiado, es decir, permanecimos dentro de la misma página pero, de algún modo, hemos ido a un lugar dentro de ella.

Cuando estamos en la bandeja de entrada vemos esta URL

https://mail.google.com/mail/u/0/?pli=1#inbox

Cuando vemos un mail vemos la siguiente

https://mail.google.com/mail/u/0/?pli=1#inbox/145511f0ec63a6d4

Lo que ocurre que por más que cambiemos algo de la URL posterior al numeral ( # ) no se ejecutará la navegación pero nosotros podemos saberlo desde Javascript (y decidir hacer algo), llamamos a esto navegación por anclas.

Navegación por anclas

Un ejemplo muy sencillo de navegación podemos verlo con referencias dentro de la misma página, vamos a Wikipedia para comprobarlo. Ingresamos a la URL del artículo sobre Backbonejs escribiendo esto en el navegador

http://en.wikipedia.org/wiki/Backbonejs

Hasta ahora todo normal, pero si agregamos al final de la URL el numeral y una referencia vemos que el navegador cambia de sitio dentro de la página

http://en.wikipedia.org/wiki/Backbonejs#References

Lo que hicimos no fue más que ir hasta un elemento dentro de la página llamado References, esto es automático, lo interesante es que podemos poner cualquier cosa después del numeral y además si presionamos el botón volver del navegador volvemos a la misma URL tal como era antes, con lo cual podemos navegar estando siempre en la misma página.

Nosotros desde Javascript podemos saber de estos cambios en la URL y hacer cosas, en esto se basa el modelo de rutas de Backbone, vamos a ver un ejemplo:

<html>
<head>
	<script type="text/javascript" src="js/vendor/jquery/jquery.js"></script>
	<script type="text/javascript" src="js/vendor/underscore/underscore.js"></script>
	<script type="text/javascript" src="js/vendor/backbone/backbone.js"></script>
	<script type="text/javascript">
		//creamos una clase Router extendiendo la clase base de Backbonejs
		var Router = Backbone.Router.extend({
			//definimos las rutas
			routes:{
				"": "home", // la url por defecto va a llamar a la función home
				"accion1": "funcion1" //la url #accion1 va a llamar a funcion1
			},
			home: function(){
				console.log("estamos en casa");
			},
			funcion1: function(){
				console.log("la acción 1 ha sido llamada");
			}			
		});
		
		//creamos un router
		var router = new Router();	
		//iniciamos el motor de navegación
		Backbone.history.start();	
	</script>
</head>
<body>
<a href="#accion1">Ir a la acción 1</a>
</body>
</html>

Básicamente cargamos este html en el navegador se escribe en la consola “estamos en casa” y cuando presionamos el link (que apunta a #acccion1) “la acción 1 ha sido llamada”, entonces con Backbone es muy simple escuchar estos cambios en la URL y llamar funciones a partir de ello.

Pasar parámetros a las rutas

Hay muchas cosas que se pueden hacer con las rutas, por ejemplo pasar parámetros, del siguiente modo:

<html>
<head>
	<script type="text/javascript" src="js/vendor/jquery/jquery.js"></script>
	<script type="text/javascript" src="js/vendor/underscore/underscore.js"></script>
	<script type="text/javascript" src="js/vendor/backbone/backbone.js"></script>
	<script type="text/javascript">
		//creamos una clase Router extendiendo la clase base de Backbonejs
		var Router = Backbone.Router.extend({
			//definimos las rutas
			routes:{
				"": "home", // la url por defecto va a llamar a la función home
				"accion1": "funcion1", //la url #accion1 va a llamar a funcion1
				"accion1/:parametro1": "funcion2" //la url #accion1 va a llamar a funcion1
			},
			home: function(){
				console.log("estamos en casa");
			},
			funcion1: function(){
				console.log("la acción 1 ha sido llamada");
			},
			funcion2: function(parametro1){
				console.log("se llama a la acción con el valor de parámetro: " + parametro1);
			}
		});
		
		//creamos un router
		var router = new Router();	
		//iniciamos el motor de navegación
		Backbone.history.start();	
	</script>
</head>
<body>
<a href="#accion1">Ir a la acción 1</a> </br>
<a href="#accion1/valor1">Ir a la acción 1 y pasar un parámetro</a>
</body>
</html>

Mágico, para no extenderme más con detalles que se pueden ver en la documentación los dejo por ahora con un link a un gist de este código, nos leemos.

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

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

Desfragmentar disquete

April 13, 2014 06:21 AM

A muchos el proceso de desfragmentar un disquete les puede parece lejano, o incluso desconocido. Allá a finales de los 80, con la utilidad Compress, incluida entre otras en PC-Tools de Central Point Software, me proporcionaba las herramientas necesarias para desfragmentar mis disquetes, tanto de 3,5 pulgadas como de 5,25 pulgadas. Los candidatos eran aquellos [...]

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

Blog Bitix

Ejemplo lista de tareas con Backbone y React

April 11, 2014 02:33 PM

Backbone
React

En anteriores entradas explicaba como hacer el típico ejemplo que se suele usar como demostración en los framework MVC de Javascript que consiste en una lista de tareas en la que se pueden añadir nuevas, marcarlas como completadas y eliminarlas. Realice este ejemplo en uno de ellos usando solo Backbone y posteriormente usando Marionette. Estos ejemplos eran parte de una serie de artículos sobre Javascript que la que mostaba como usar muchas otras herramientas como Require JS, Mustache, logging con javscript, capturar errores en javascript, introducción a Backbone, lista de tarea con Backbone, RESTEasy y Tapestry, pruebas unitarias con Jasmine y Sinon, Usar Grunt para ejecutar teses unitarios de código Javascript y que constituyen parte del actual «estado del arte» en cuanto a desarrollo con Javascript.

La lista de tareas aunque es un ejemplo sencillo sirve perfectamente como ejercicio para mostrar el uso de los frameworks MVC. En esta entrada voy a mostrar como hacer el mismo ejemplo usando Backbone y React y veremos, en mi opinión, que el ejemplo es mucho mas sencillo y lógico.

La parte más complicada y menos intuitiva del ejemplo de la lista de tareas con solamente Backbone o con Marionette probablemente era la V del MVC. Backbone es un framework que deja bastante libertad al desarrollador pudiendo usar únicamente las partes que necesitemos de él, sin embargo, esta sencillez nos obliga a gestionar ciertas «tareas de fontanería» y repetitivas nosotros mismos como la gestión de las vistas y la memoria. Marionette trata de dar solución a parte de estas tareas necesarias además de proporcionar unas guías y arquitectura para el desarrollo de las aplicaciones. Sin embargo, aún con Marionette la construcción de la parte de la vista con el uso de ItemView, CollectionView y Layout comentados en la documentación me resultó poco intuitivo y en cierta medida todavía complicado, no acabé convencido del todo, con React he acabado con la sensación que hacer algo más complejo que este ejemplo es algo al menos manejable.

React es una librería que en algunos casos se está usando en aplicaciones junto con Backbone para proporcionar la parte de la vista y controlador que en conjunto definen lo que en React se conoce como un componente. De esta manera Backbone proporciona los modelos, eventos, routing , … y React proporciona la representación de esos modelos en html y el código encargado de gestionar el estado de esa vista. React tiene ciertas ventajas adicionales por su funcionamiento y es que cuando se cambia algo en la vista no se reemplaza el html completo de la vista y se inserta uno nuevo sino que React busca las diferencias entre la vista actual y la nueva y realiza únicamente los cambios necesarios para tener la vista nueva, esto tiene la ventaja de que el proceso es más eficiente y rápido y puede notarse en aplicaciones con muchos datos gestionados en el cliente. Pero lo que más me ha gustado de React es la definición del concepto de componente (vista + controlador) que por una parte hace que la creación de las vistas es mucho más sencilla e intuitiva que en Backbone o Marionette y que junto con el controlador permite crear piezas reusables de código.

Los componentes de React reemplazan a las vistas de Backbone y vistas, controladores y layouts de Marionette. En el nuevo ejemplo los cambios principales se encuentran en el archivo tareas.js que contiene el código de la aplicación de lista de tareas.

<noscript><pre><code>define('tareas', [ 'jquery', 'underscore', 'backbone', 'react', 'mustache', 'plantillas', 'i18n!i18n/nls/mensajes' ], function($, _, Backbone, React, Mustache, Plantillas, Mensajes) { function render(plantilla, datos, mensajes) { var d = datos || {}; var m = mensajes || {}; var vista = _.extend(d, { message: m }); var p = Plantillas[plantilla]; var pp = p(); return pp(vista); } // An example generic Mixin that you can add to any component that should react // to changes in a Backbone component. The use cases we've identified thus far // are for Collections -- since they trigger a change event whenever any of // their constituent items are changed there's no need to reconcile for regular // models. One caveat: this relies on getBackboneModels() to always return the // same model instances throughout the lifecycle of the component. If you're // using this mixin correctly (it should be near the top of your component // hierarchy) this should not be an issue. var BackboneMixin = { componentDidMount: function() { // Whenever there may be a change in the Backbone data, trigger a reconcile. this.getBackboneModels().forEach(function(model) { model.on('add change remove reset', this.forceUpdate.bind(this, null), this); }, this); }, componentWillUnmount: function() { // Ensure that we clean up any dangling references when the component is // destroyed. this.getBackboneModels().forEach(function(model) { model.off(null, null, this); }, this); } }; var Tarea = Backbone.Model.extend({ urlRoot : 'rest/tareas/tarea', defaults : { id : null, descripcion : '', completada : false }, toogle: function() { this.set('completada', !this.get('completada')); } }); var Tareas = Backbone.Collection.extend({ url: 'rest/tareas', model: Tarea, findCompletadas: function() { return this.models.filter(function(tarea) { return tarea.get('completada'); }); }, removeCompletadas: function() { _.each(this.findCompletadas(), function(tarea) { tarea.destroy(); }); } }); var TareaComponent = React.createClass({ componentDidMount: function() { var _this = this; this.ui = { completada: $('input[name=completada]', this.getDOMNode()) }; this.ui.completada.change(function(event) { _this.props.tarea.toogle(); _this.props.tarea.save(); }); }, render: function() { // return ( // &lt;label className=&quot;checkbox&quot;&gt; // &lt;input type=&quot;checkbox&quot; name=&quot;completada&quot; checked={(this.props.tarea.get('completada'))?'checked':''}/&gt; &lt;span className={this.props.tarea.completada}&gt;{this.props.tarea.get('descripcion')}&lt;/span&gt; // &lt;/label&gt; // ); return React.DOM.label({className:'checkbox'}, React.DOM.input({type:'checkbox', name:'completada', checked:(this.props.tarea.get('completada'))?'checked':''}), React.DOM.span({className:this.props.tarea.completada}, this.props.tarea.get('descripcion')) ); } }); var TareasComponent = React.createClass({ render: function() { var tareas = this.props.tareas.map(function(tarea) { // return ( // &lt;li&gt;&lt;TareaComponent tarea={tarea}/&gt;&lt;/li&gt; // ); return React.DOM.li(null, TareaComponent({tarea:tarea}) ); }, this); // return ( // &lt;ul&gt;{tareas}&lt;/ul&gt; // ); return React.DOM.ul(null, tareas); } }); var EstadoComponent = React.createClass({ render: function() { var d = this.getData(); var m = { 'COMPLETADAS_tareas_de_TOTAL_completadas': Mustache.render(Mensajes.COMPLETADAS_tareas_de_TOTAL_completadas, d), 'Muy_bien_has_completado_todas_las_tareas': Mensajes.Muy_bien_has_completado_todas_las_tareas, }; var estado = render('estado', d, m); // return ( // &lt;span className=&quot;estado&quot;&gt;{estado}&lt;/span&gt; // ); return React.DOM.span({className:'estado'}, estado); }, // Métodos getData: function() { var completadas = this.props.tareas.findCompletadas().length; var total = this.props.tareas.length; return { completadas: completadas, total: total }; } }); var TareasApp = React.createClass({ mixins: [BackboneMixin], getBackboneModels: function() { return [this.state.tareas]; }, getInitialState: function() { return {tareas: new Tareas()}; }, componentDidMount: function() { var _this = this; this.ui = { nuevaTarea: $('input[name=nuevaTarea]', this.getDOMNode()), limpiar: $('input[name=limpiar]', this.getDOMNode()) }; this.ui.nuevaTarea.focus(); // Eventos this.ui.nuevaTarea.keypress(function(event) { // Comprobar si la tecla pulsada es el return if (event.which == 13) { var descripcion = _this.ui.nuevaTarea.val().trim(); // Comprobar si se ha introducido descripción de la tarea if (descripcion == '') { return; } // Añadir la tarea y limpiar el input var tarea = new Tarea({ descripcion: descripcion, completada: false }); _this.addTarea(tarea); _this.ui.nuevaTarea.val(''); } }); this.ui.limpiar.click(function() { _this.removeTareasCompletadas(); }); }, render: function() { // return ( // &lt;div&gt; // &lt;h2&gt;{Mensajes.Lista_de_tareas}&lt;/h2&gt; // &lt;input type=&quot;text&quot; name=&quot;nuevaTarea&quot; className=&quot;form-control&quot; placeholder={Mensajes.Introduce_una_nueva_tarea} /&gt; // &lt;TareasComponent tareas={this.state.tareas} /&gt; // &lt;EstadoComponent tareas={this.state.tareas} /&gt; // &lt;br/&gt; // &lt;input type=&quot;button&quot; name=&quot;limpiar&quot; value={Mensajes.Limpiar} disabled={(this.isTareasCompletadas())?null:'disabled'} className=&quot;btn&quot; /&gt; // &lt;/div&gt; // ); return React.DOM.div(null, React.DOM.h2(null, Mensajes.Lista_de_tareas), React.DOM.input({type:'text', name:'nuevaTarea', className:'form-control', placeholder:Mensajes.Introduce_una_nueva_tarea}), TareasComponent({tareas:this.state.tareas}), EstadoComponent({tareas:this.state.tareas}), React.DOM.br(), React.DOM.input({type:'button', name:'limpiar', value:Mensajes.Limpiar, disabled:(this.isTareasCompletadas())?'':'disabled', className:'btn'}) ); }, // Métodos isTareasCompletadas:function() { return this.state.tareas.findCompletadas().length &gt; 0; }, addTarea: function(tarea) { this.state.tareas.add(tarea); tarea.save(); }, removeTareasCompletadas: function() { this.state.tareas.removeCompletadas(); }, resetTareas: function(tareas) { this.state.tareas.reset(tareas); }, fetch: function() { // Con reset:true solo se lanza un evento para todos los cambios que se produzcan en la colección this.state.tareas.fetch({reset:true}); } }); return { Tarea: Tarea, Tareas: Tareas, TareaComponent: TareaComponent, TareasComponent: TareasComponent, EstadoComponent: EstadoComponent, TareasApp: TareasApp }; });</code></pre></noscript>

El resultado es el siguiente:

Los elementos de las vistas se recomienda definirlas con los elementos que proporciona React con React.DOM, pueden definirse más al estilo de html con jsx pero esto hace que el javascript haya de compilarse para transformar ese jsx/html a los elementos React.DOM, el mayor problema es que esto es un proceso costoso lo que puede ralentizar la carga de una página y que el compilador tiene un tamaño considerable de unos 300 KiB. El JSX es más claro y parecido al resultado final que el código equivalente React.DOM pero aún así el código javascript es suficientemente claro. Si aún así quisiésemos usar JSX lo recomendable sería que los archivos con contenido jsx se precompilase en un momento anterior de enviarlo al cliente, posiblemente antes del despliegue de la aplicación en el servidor.

Para probar el código podemos hacerlo abriendo el archivo test/javascript/SpecRunner.html, sin embargo, deberemos hacerlo con Chrome o Chromium y lanzándolo con un parámetro opcional para permitir la carga de los archivos.

<noscript><pre><code>$ chromium --allow-file-access-from-files</code></pre></noscript>

También podríamos probarlo usando gradle con:

<noscript><pre><code>$ ./gradlew jasmine</code></pre></noscript>

Sin embargo, PhantomJS que es lo que se utiliza para simular el navegador en las pruebas con jasmine y grunt, no soporta la función bind produciéndose la siguiente excepción al usarse en la librería de React.

<noscript><pre><code>Error: define: 'undefined' is not a function (evaluating 'RegExp.prototype.test.bind( &gt;&gt; /^(data|aria)-[a-z_][a-z\d_.\-]*$/ &gt;&gt; )')</code></pre></noscript>

Para evitarlo debemos añadir un polyfill. Deberemos añadir los polyfills de cujojs/poly, podemos hacer uso de ellos con RequireJS basta como añadirlo como dependencia:

<noscript><pre><code>define(['poly/function', 'specs/tareas-specs'], function() { });</code></pre></noscript>

Este problema de la función bind ya esta incluido como peticion en PhantomJS y probablemente se resuelva en la versión 2.0.

El ejemplo con el código fuente completo de este ejemplo está en mi repositorio de GitHub, puedes probarlo en tu equipo con el siguiente comando:

<noscript><pre><code>$ ./gradlew tomcatRun</code></pre></noscript>

Referencia:
Introducción y ejemplo de RequireJS
Introducción y ejemplo de Mustache
Logging en Javascript con log4javascript
Capturar errores de Javascript
Optimizar módulos de RequireJS y archivos Javascript
Introducción y ejemplo de Backbone.js
Ejemplo de pruebas unitarias en javascript con Jasmine y Sinon
Ejemplo lista de tareas con Marionette
Usar Grunt para ejecutar teses unitarios de código Javascript
Function/bind#Compatibility
React, JSX, and CoffeeScript

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

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

Visual Models

April 08, 2014 08:37 PM

Simple y práctico, así calificaría este artículo, se dice que a veces lo simple es lo mejor, aunque en modelos visuales yo tambien le daría mucho peso a UML sin que esto represente complicarte la vida, al contrario creo que este puede ser muy práctico.

Visual Models

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

Variable not found

Back to my roots, el evento de Gusenet que no debes perderte

April 08, 2014 10:23 AM

Gusenet(Léase con voz radiofónica) De los creadores de “Yo Node, tú XAML”, llega ahora “Back to my roots”, el nuevo evento con el que los chicos de Gusenet piensan liarla de nuevo y mantener su puesto como uno de los festivales frikis más potentes del panorama nacional.

Torrevieja!Tendrá lugar los días 25, 26 y 27 de Abril en Torrevieja, Alicante (no puedo evitar decirlo, crecí con el 1-2-3 ;-D), un entorno inmejorable para disfrutar de un fin de semana en la costa rodeado de gente que comparte tu misma pasión por la tecnología. Y cerveza, mucha cerveza, cortesía de la organización.

El registro es gratuito y debéis hacerlo cuanto antes a través del siguiente enlace: http://www.eventbrite.es/e/entradas-back-to-my-roots-10635022639.

Las charlas previstas a día de hoy son las siguientes:

Ponente Charla
Marc Estrada Pague una, llévese dos (apps para múltiples dispositivos).
Marc Rubiño AngularJS – Poli bueno, poli malo.
Juan María Hernández No pierdas tiempo escribiendo tests.
Alfredo Fernández Todo un misterio (es secreto: probablemente algo cañero de JS).
Juan Quijano Coded UI, iniciación a pruebas funcionales del interfaz gráfico.
Quique Martínez Video OnDemand y Live Streaming. Entrega de vídeo multiplataforma.
Luis Ruíz Pavón CQRS – Hasta el infinito y más allá
Alberto Díaz & Adrián Díaz Porque no veo otra cosa nada más que SharePoint
Pedro J. Molina Backends y arquitecturas para servicios con Radarc
Alex Casquete Programación funcional reactiva
Eduard Tomás Videojuegos web en tiempo real con Katana, SignalR y NancyFx
Roberto Luis Bisbé Firefox OS: Javascript vuela en primera clase
Enrique Catalá Nuevo motor relacional In-memory OLTP en SQL Server 2014
Bruno Capuano Coding 4 Fun, Kinect V2, Leap Motion, Unity3D, etc …
Josue Yeray & Santiago Porras Charla secreta
Isabel Cabezas & Toni Recio Javascript y por qué no comparar la velocidad con el tocino
Carlos Carrillo Windows Azure Mobile Services ahora con .NET
Juan Manuel Servera Introducción a Roslyn
Miguel Egea Diseñando bases de datos relacionales para mantener históricos
Eladio Rincón Índices compuestos para desarrolladores
Fernando G. Guerrero Reflexiones sobre el futuro, de alguien que ha peleado ya algunas recesiones
Fernando Escolar Load Tests: ¿sobrevivirías al efecto menéame?
Pedro Hurtado, LLuis Franco y Sergio León Dos tontos muy tontos y un tío con futuro
 


Y como los organizadores son gente importante, hasta les hacen entrevistas ;-) Podéis leer y oír algo más sobre el evento siguiendo este link: GUSENET nos habla de su mega-evento en Torrevieja el proximo 26 de Abril…

Por mi parte, aunque todavía no sé si podré asistir personalmente por problemas de agenda, como mínimo lo haré en espíritu mediante una pequeña colaboración ;-D: Entre los asistentes se sorteará una copia firmada de mi libro “SignalR Programming in Microsoft ASP.NET”!!


Publicado en Variable not found.

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

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

The internet of Things and CRM

April 07, 2014 11:27 PM

Interesante artículo que víncula el llamado Internet de las cosas y CRM, esta claro el mensaje Social, Mobile, Cloud  y Big Data

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

proyectos Ágiles

Adopción de Agile en la empresa. Entrevista revista Tendencias

April 07, 2014 09:54 PM

A continuación aparece una entrevista realizada para la revista Tendencias, donde entre otros temas se habla sobre qué es Agile, el porqué de Agile, qué implica adoptar Agile en la empresa, el rol del Scrum Master, la motivación y compromiso de personas, el liderazgo en un entorno Agile, métricas, quién utiliza Agile y el uso de Agile que hizo Obama en su campaña del 2012.

question-postits

 

 

1- ¿Cómo definiría brevemente la filosofía agile?
Agile es una forma de obtener mejores resultados basada en conseguir equipos de alto rendimiento, con el cliente integrado en el equipo, hacer que las personas estén motivadas, tener feedback rápido sobre el producto final que se está desarrollando y reflexionar de manera regular sobre cómo mejorar el proceso de trabajo. Para conseguir esto se necesita priorizar los objetivos a conseguir según el valor que aportan al receptor final de un proyecto/servicio, ser flexible en la incorporación de cambios, crear equipos multidisciplinares, auto-organizados y estables que conjuguen la simplicidad con la excelencia técnica de la solución.
 
2- ¿Cuándo y por qué decidió asumir esta filosofía laboral y, tal vez, personal? ¿Qué ha significado y está significando para usted en su vida diaria?
Mi contacto inicial con Agile (XP) fue en algunos proyectos en el 2002.  Tras estar trabajando en diversas empresas y con distintas metodologías, en el 2008 decidí que todo mi trabajo se basase al máximo en esa filosofía (lo cual significaba crear el contexto necesario para eso), para poder ejecutar proyectos complejos con mayor garantía de éxito. A nivel personal, me ha implicado tener que estar aprendiendo continuamente cómo mejorar en mi parte de soft-skills, un reto mucho más difícil (pero más agradecido) que el de aprender nuevas técnicas de gestión o desarrollo. Esto al final tiene que repercutir en que, a nivel laboral y personal, mi vida (y la de los que me rodean) sea más feliz (si no, no valdría la pena).
 
3- ¿Es fácil virar hacia agile?
Ser ágil no es sencillo, dependiendo del contexto puede ser un cambio cultural importante, que depende también de la idiosincrasia de las personas y de sus capacidades. Ser ágil requiere disponer de personas que estén realmente dispuestas a trabajar en equipo y sean abiertas de mente, que tengan ganas de probar cosas nuevas, de aprender y de mejorar, no dar por hecho que lo que no funciona bien “siempre ha sido así”.
 
open-minded
 
4- ¿De qué forma los principios ágiles están cambiando los objetivos y la misión de los departamentos de Recursos Humanos?
El foco pasa a estar no sólo en el crecimiento del individuo y en el satisfacer sus motivaciones “intrínsecas” (todo esto es básico), sino además en la creación de equipos (encaje de personas, team building, …), un equipo es un activo para la empresa y cuesta tiempo y esfuerzo crearlo, por lo que hay en dotar a sus miembros con soft-skills y técnicas para mejorar cómo se relacionan (team agreements, gestión de conflictos, …) y hay que modelar la cultura a nivel de empresa para que la colaboración sea algo "nuclear". Esto implica introducir en la empresa valores explícitos de trabajo en equipo y de apertura de mente, dar mensajes para conseguir alineamiento en esto, hacer un reconocimiento explícito de los comportamientos aceptados, contratar personas que tengan estos principios, hacer coaching a quienes tienen más dificultades, despedir a los que tras repetidos esfuerzos no se ha conseguido integrar o adaptar y siguen actuando de la manera contraria, etc.
 
5- Trabajar con personas motivadas y comprometidas es, según la filosofía Agile, una condición indispensable, pero ¿no le parece una utopía conseguir que los trabajadores estén siempre motivados y comprometidos?
La mayoría de las personas necesitan estar motivadas en su trabajo, son muchas horas como para no disfrutarlo mínimamente y “realizarse” (sea aprender cosas nuevas, hacer algo que sea importante, tener un margen para creatividad, que el trabajo no sea aburrido o tener reconocimiento). Conseguir que las personas estén motivadas no es sencillo, siempre habrán momentos complicados, donde la motivación bajará, pero esto no es opcional, el trabajo está realizado por personas, no son máquinas, y las personas motivadas hacen cosas increíbles. La motivación depende de la pripia persona y del management, que es quien debería crear el contexto para que haya partes del trabajo que sean motivadoras. Otro problema es cuando las personas ya vienen motivadas de casa pero en el trabajo son sus responsables los que les desmotivan.
 
6- El trabajo en equipo es clave, pero ¿no se ha encontrado con que muchas veces en los equipos acaban trabajando duro unos cuantos y el resto no tanto?
Cierto, en este caso hay una disfunción que, además de reducir el rendimiento y motivación general, puede crear tensiones. Forma parte de las funciones del responsable del "crecimiento" de ese equipo y del management identificar esta situación y ponerle remedio. En entornos maduros es el propio equipo el que, tras identificar el problema, analiza cuál es la razón por la que sucede esto y trabaja con el responsable para mejorar la situación (falta de motivación o de capacidades de los que trabajan menos, incompatibilidad de caracteres, falta de criterios o principios comunes, etc.). Tras trabajar las mejoras, si no hay resultado, el propio equipo y su responsable deberían tomar la decisión de sacar a esas personas de ese equipo.
green-growth
 
7- ¿La filosofía agile se puede aplicar sólo a parte de una empresa o tiene que aplicarse íntegramente?
Cuanto más extendida esté en la empresa, más oportunidades tendrá para proporcionar productos o servicios mejores y de calidad. El trabajo en equipo es un factor competitivo diferencial en las empresas más punteras. De cualquier manera, como he comentado antes, la adopción completa de Agile dependerá mucho de la cultura de la empresa y su capacidad para enfocarse toda en el cliente final.
 
8- ¿Qué caracteriza a un líder agile?
Un líder ágil es una persona que entiende que es quién es y está donde está por las personas de sus equipos. Se enfoca en crezcan en competencia, les enseña el "oficio", es un líder a al servicio del equipo (él es quien va a averiguar cuales son sus necesidades para que puedan hacer mejor su trabajo y se encarga quitarles los impedimentos que tengan), conoce a su gente, se preocupa por la motivación de cada individuo (no lo desmotiva), hace que trabajen en equipo, que colaboren y piensen juntos, mantiene una estrategia de mejora de su área con visión en el medio plazo (no es cortoplacista) y practica con el ejemplo, todo ello con una óptica positivay constructiva.
 
9- ¿El hecho de que sea tan importante la comunicación cara a cara en el día a día de una empresa agile hace que las nuevas tecnologías que promocionan la comunicación online no sean tan imprescindibles?
Si bien la comunicación cara a cara es casi la mejor opción (sólo superable si además se utiliza una pizarra blanca), la realidad es que hoy en día bastantes proyectos se realizan de manera distribuida por diversas razones. En este punto, es fundamental disponer de buenos sistemas de videoconferencia, compartición de pantallas, posibilidad de editar documentos por varios usuarios simultáneamente, diagramación colaborativa, etc.
 
10- ¿Por qué la filosofía agile es especialmente útil en contextos de incertidumbre?
Porque Agile también es un método de gestión de riesgos. Ya desde el inicio de un proyecto se priorizan los objetivos en función del valor que aportan al receptor del proyecto. También se divide la complejidad en partes más pequeñas que siempre tienen que proporcionar un trocito adicional de producto final, por que es crítico disponer de feedback rápido. Para ello el cliente revisa cada uno de estos incrementos de manera que se asegura que se va de la mano con él (para no tener sorpresas al final del proyecto). Adicionalmente, diariamente el equipo se sincroniza para identificar problemas, fomentando la ayuda mutua para desbloquearlos. Por último (y este es un aspecto nuclear de Agile, sino no se puede decir que sea ágil) el equipo dispone de tiempo “de calidad” de manera regular para reflexionar, para evaluar cómo está trabajando y poder mejorar la situación. 
 
risk_management
 
11- ¿Por qué aparece la necesidad de la filosofía agile?
La filosofía Agile aparece como reacción a planteamientos de gestión tradicionales, heredados de la ingeniería clásica, que no tienen tanto en cuenta el factor humano (capacidades, relaciones) que hay en entornos de gran incertidumbre y, especialmente, donde hay trabajadores de conocimiento. Más que focalizarse en los procesos de trabajo por encima de todo (como tienden a hacer los métodos tradicionales), los métodos ágiles asumen lo que empíricamente sabemos de la realidad de los proyectos: la importancia de disponer de gente competente y motivada que sea capaz de trabajar en equipo, apoyarles y confiar en ellos, la necesaria colaboración continua del cliente (no sólo al principio y al final del proyecto), la realidad de que va a ser necesario realizar cambios durante el proyecto, que el papel finalmente no “lo aguanta todo”, que el “momento de la verdad” sólo es cuando enseñas al cliente alguna parte de producto final, el foco en la simplicidad de las soluciones y el trabajar a un ritmo sostenible para ser más productivos. Adicionalmente los métodos ágiles son antagonistas del caos, introducen disciplina en el proceso y foco en la calidad del trabajo.
 
12- ¿Qué opina del uso que hizo Obama de Agile durante la campaña de 2012?
En esa campaña acertaron en utilizar Agile para gestionar un contexto complejo que necesitaba de resultados y ajustes rápidos. Además, como dice la primera línea del Agile Manifesto, el primer factor clave fue encontrar a gente “espabilada” y motivada por el reto (un aspecto crítico para conseguir soluciones rápidamente). Después también fue acertado en lanzar rápidamente un “producto” suficientemente bueno (no perfecto, incluso con defectos, pero con lo más relevante) e irlo iterando y repriorizando rápidamente, para tener mucha flexibilidad respecto a lo que fuese pasando en el contexto (en cada momento de una campaña las prioridades cambian). Otro acierto fue apoyar en datos objetivos las decisiones de qué era lo más importante desarrollar en cada momento, para que fuese útil para los usuarios finales. El hecho de que Agile proporciona mucha transparencia,visibilidad y feedback sobre el progreso y resultados del proyecto (en este caso a nivel semanal) a todas las personas con poder de decisión (Stakeholders) también les ayudó de manera significativa a que ganaran confianza en el método de trabajo (no estaban familiarizados con un método de “aprendizaje” y desarrollo continuo sobre un producto software) que, curiosamente, basándose en datos de velocidad empíricos, proporcionaba una gran fiabilidad acerca de cuándo determinados hitos se alcanzarían.
 
obama-sport
 
13- La filosofía Agile es intrínseca al Scrum Master? ¿qué papel juega esta nueva figura?
El Scrum Master es el “entrenador del equipo”, desde una perspectiva de coaching su objetivo es el hacer crecer un equipo para que sea de alto rendimiento (incluyendo en este equipo al cliente), donde la auto-organización y la motivación son aspectos clave. Para ello, el Scrum Master entiende cuáles son los valores y principios de Agile y facilita una serie de prácticas y reuniones con el fin de que el equipo piense junto, se creen sinergias, se complementen, se ayuden y el trabajo fluya. Adicionalmente, se dedica a quitar las “piedras del camino” (lo que llamamos "impedimentos") de manera que este equipo se pueda dedicar al máximo a aportar valor.
 
14- ¿Cómo podemos medir un proyecto en Agile?
Dependiendo del tipo de contexto, entre las principales métricas podemos encontrar las siguientes: el valor que se está aportado (si lo que se está desarrollado es lo que se esperaba o produce el resultado deseado), la productividad del equipo de trabajo (también llamada “velocidad”), la calidad del producto, el tiempo que falta para acabar, el tiempo de entrega de peticiones de trabajo, la motivación del equipo, etc.
 
15- ¿Qué empresas se han convertido en referencia tras asumir la filosofía agile?
Destacaría por más conocidas (entre muchas otras que me dejo): Google, SAP, Spotify, Salesforce, Amazon, eBay, BBC, Atlassian, Ferrari, InfoJobs, Idealista y la industria de los videojuegos.
 
16- ¿Se puede dar marcha atrás? ¿ha habido casos?
Sí, el cambio cultural puede ser muy fuerte dependiendo de la idiosincrasia actual de la empresa. Otro factor crítico de no éxito es no contar con algún experto en la materia (experto = experiencia de varios años trabajando ágilmente e introduciendo esta filosofía de trabajo en diferentes contextos) para que guíe en la transición haciendo coaching en la “trinchera”. Hay bastantes casos de fracaso, bien por falta de ambiente colaborativo en la empresa, apertura de mente y ganas de probar y aprender, así como por el “hacérselo por su cuenta”, lo que lleva a errores “de libro” y transiciones demasiado dolorosas por no entender lo que se está haciendo, lo cual quita las ganas de volver a ponerse en 2 o 3 años. 
 
17- ¿Cree que todas las empresas se pueden permitir el equilibrio salarial?
Si se refiere a que todo el mundo en la empresa cobre más o menos lo mismo, no creo que eso tenga mucho sentido, ni siquiera en una empresa ágil :)

 

Artículos relacionados:

 

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

Variable not found

Enlaces interesantes 153

April 07, 2014 12:10 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

Testeando sitios web con F# y Canopy

April 07, 2014 05:06 AM

Todos los que seguís este blog sabéis que me interesa mucho buscar la mejor forma de testear aplicaciones y que considero que unos buenos tests son fundamentales para conseguir aplicaciones más sólidas y dormir más tranquilo. A lo largo de los posts he hablado mucho sobre tests unitarios, tests de aprobación e incluso he tocado por encima los tests de extremo a extremo.

En este post vamos a ver una nueva herramienta para escribir tests sobre páginas web que me ha llamado especialmente la atención: canopy.

¿Qué es canopy?

Canopy es una herramienta open source que nos permite escribir tests sobre sitios web usando un DSL desarrollada en F#. Internamente utiliza Selenium, lo que nos permite testear directamente sobre distintos navegadores reales.

La documentación de canopy, aunque escueta, es lo bastante clara como para poder empezar a escribir tests sin mucho esfuerzo y, aunque no soy un gran fan de sintaxis de F#, tengo que reconocer que el DSL está muy logrado y permite escribir tests bastante claros.

Para usarlo sólo es necesario instalarlo desde Nuget. Esto podemos hacerlo en cualquier proyecto de .NET (sí, también C#), pero merece la pena escribir los tests en F#, por lo que lo más recomendable es escribir los tests en un proyecto de consola de F#.

Testeando MegaFacts

Como toma de contacto, vamos a usar canopy para testear la aplicación de ejemplo MegaFacts que he usado tanto en el tutorial de node.js y express, como en el tutorial de compojure, concretamente, testearemos la implementación de compojure.

Lo importante es que tengáis en cuenta que, puesto que estamos testeando desde el propio interface web, nos da igual cómo esté implementado por detrás, ya que estaremos interactuando directamente con el navegador.

La página principal (y única) de MegaFacts era algo así:

Mockup de la página de Mega Facts

A la izquierda se muestra una lista de “héroes” sobre los que podemos pulsar para mostrar los “facts” asociados a cada uno y añadir nuevos facts. Es importante reseñar que la página en sí no está pensada para ser testeada, pero aun así podremos conseguir unos tests relativamente legibles.

Los tests los vamos a organizar en un módulo llamado MegaFacts en el que lo primero que haremos será incluir los módulos que necesitamos:

module MegaFacts

open canopy
open runner

A continuación, añadiremos un Page Model para independizar un poco los tests de la estructura real de la página:

let factsUrl = "http://localhost:3000"

// Enlaces a los diferentes héroes
let heroArturo = "#heroes li:nth-of-type(1) a"
let heroBruce = "#heroes li:nth-of-type(2) a"
let heroChuck = "#heroes li:nth-of-type(3) a"

// Información sobre el héroe selecciando
let currentHeroName = "#right-column h2"
let currentFacts = "#facts li"

// Controles para añadir facts
let newFactText = "#new-fact"
let addNewFact = "#add-new-fact"

En el Page Model estamos “poniendo nombres” a los diferentes elementos que componen la página, los cuales identificamos mediante selectores CSS. Aquí se nota que la página no está diseñada para ser testeada y hace falta usar algunos selectores un poco rebuscados, pero al menos podemos testearla y, gracias al Page Model, si la cambiamos la estructura de la página para adecentarla un poco, sólo necesitaremos actualizar el Page Model y nuestros tests seguirán funcionando.

Ahora que ya tenemos todo preparado, vamos a escribir nuestro primer test, que consistirá en validar que al pulsar sobre nombre de cada héroe se muestran sus facts asociados:

let browseFacts _ =

    context "Consultando los facts de cada héroe"

    url factsUrl

    displayed "#heroes"

    "Al seleccionar un héroe se muestran sus facts" &&& fun _ ->
        
        click heroChuck

        currentHeroName == "Chuck Norris"

        currentFacts *= "Chuck Norris borró la papelera de reciclaje."

        click heroArturo

        currentHeroName == "Arturo Pérez-Reverte"

        currentFacts *= "Pérez-Reverte se baja música en casa de Ramoncín."

En este código podemos ver en acción el DSL de canopy. Usando context podemos indicar qué es lo que estamos testando y con la función (infija) &&& definimos nuestros tests. Veis que tenemos acciones, como url que nos permite navegar a una página o click para interactuar con un elemento, y aserciones, como displayed para comprobar que se muestra un elemento, == para validar el texto de un elemento, o *= que valida si alguno de los elementos de la colección contiene el texto indicado.

Vamos a ver otro test en el que comprobemos que podemos añadir nuevos facts a un héroe:

let addFact _ =
    
    context "Añadiendo un nuevo fact"

    "Al añadir un nuevo fact se muestra en la lista de facts" &&& fun _ ->

        click heroChuck

        currentHeroName == "Chuck Norris"

        newFactText << "Object hereda de Chuck Norris"

        click addNewFact

        currentFacts *= "Object hereda de Chuck Norris"

La única novedad de este test con respecto al anterior es la función << para establecer el texto de un control, en este caso el textarea usado para introducir el nuevo fact.

Por conveniencia, todos los tests de este módulo los podemos agrupar en una única función que se encargue de ejecutarlos secuencialmente:

let all _ =
    browseFacts()        
    addFact()

Si tuviésemos más páginas en nuestra aplicación podríamos definir módulos para cada una de ellas, cada uno de ellos con su función all para agruparlos. Finalmente, para ejecutar los tests, en el punto de entrada de nuestra aplicación de consola tendremos algo así:

open canopy
open runner

start firefox

MegaFacts.all()

run()

Simplemente abrimos un navegador (en este caso Firefox), definimos todos los tests de los módulos que tengamos y usamos la función run para ejecutarlos.

Para ejecutarlos, necesitamos que la página tiene que estar accesible (podríamos incluso levantar el servidor donde está alojada en el propio test) y ejecutar la aplicación de consola que acabamos de crear. Veréis como se abre un navegador y se empieza a interactuar con él para completar las acciones que hemos definido en los tests.

El resultado será algo así:

canopy-output

Por si queréis verlo más detenidamente, aquí os dejo el código completo del ejemplo y recordad que para ejecutarlo hace falta lanzar el servidor web de MegaFacts.

Conclusiones

Canopy es un proyecto muy interesante para realizar tests de extremo a extremo. Su sintaxis resulta clara, sencilla y natural. Como habéis visto en el ejemplo, es posible testear sin mucha dificulta páginas que, en un principio no estaban diseñadas para ser testeadas (aunque es verdad que pensar un poco en los tests a la hora de diseñar las págians simplifica luego el mantenimiento de los tests).

Una de las cosas que más me gusta de Canopy es que está desarrollado en F#. No es tanto por F# en si (todavía no tengo muy claro si me gusta o no el lenguaje), pero el hecho de ver que .NET es cada vez más políglota me hace tener más esperanzas en el futuro de la plataforma.

No hay posts relacionados.

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

Arragonán

Semana 304

April 07, 2014 02:16 AM

Semana movidita en cuanto a posibles nuevas colaboraciones a priori puntuales, tuve que invertir tiempo en un par de reuniones y en algún que otro mail de cara a preparar propuestas. Llevaba tiempo sin hacerlo y precisamente me rondaba en la cabeza el buscar algún proyecto o producto “no muy grande” en el que colaborar a partir de mayo, ni que me hubieran olido.

El martes me pasé por las Geek Talks tras un par de meses sin hacerlo, estuvimos hablando sobre las herramientas de gestión/organización que utilizamos. El miércoles me tuve que cruzar la ciudad tras jugar a fútbol sala para unirme a cenar con Jaume, Bea y una buena representación de los habituales de la comunidad local. El jueves me fui de concierto guitarrero, que me moló bastante: No Truck Truckers y Total Heels. El viernes publicaron un post mío, que terminé por fin esta misma semana, en el blog de CartoDB: Mapping food banks in Spain with CartoDB.

Sobre los proyectos en los que ando, mucha variedad:

  • En mhop estuve implementando en el frontend el poder buscar productos por etiqueta y en poder incrustar también vídeos de vimeo.
  • Para minchador estuve haciendo cambios en la landing, hay que darle vueltas aún al copywriting y hacer un rediseño en condiciones.
  • Arreglé un scraper de ShuttleCloud que se había roto.
  • Retomé cosas pendientes de proyectoSinNombre, básicamente algunos detalles relacionados con Refinery CMS.

Buena semana.

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

Variable not found

Ya está aquí: SignalR Programming in Microsoft ASPNET

April 06, 2014 05:46 PM

Por fin llegó el momento que estaba esperando desde hace tiempo: tras muchos meses de trabajo y preparativos, ya está disponible mi libro “SignalR Programming in Microsoft ASP.NET” :-) ¡¡Hurra!!

Publicado directamente en inglés por Microsoft Press, ha sido desde su origen un proyecto mucho más ambicioso que mi anterior incursión en el mundo literario, que seguro recordaréis, principalmente porque se trata de un libro con una difusión, repercusión y alcance mucho mayor que el anterior, y al que hemos tenido que dedicar muchísimo esfuerzo, tiempo e ilusión todos los implicados (¡que no son pocos!) para lograr un resultado que esperamos esté a la altura de las circunstancias.

El libro tiene más de 250 páginas a través de las cuales se describen tanto temas básicos como aspectos avanzados de la programación con la versión 2 de SignalR. El índice resumido es el siguiente:
  1. Internet, asynchrony, multiuser… wow!
  2. HTTP: you are the client, and you are the boss
  3. Introducing SignalR
    Estos tres primeros capítulos introducen las aplicaciones asíncronas en tiempo real y los conceptos básicos que necesitamos conocer para trabajar con SignalR: qué es, qué nos aporta, y qué mecanismos hacen que todo esto funcione.
  4. Persistent connections En el cuarto capítulo comenzamos ya a trabajar con conexiones persistentes, tanto en el lado servidor como en el cliente, describiendo en detalle las APIs que ofrece SignalR para comunicar ambos extremos.
  5. Hubs Aquí se describe profundidad el uso de hubs, tanto en el lado cliente como en el servidor, describiendo detalladamente las herramientas disponibles para enviar y recibir datos desde ambas partes, mantener el estado, implementar trazas, y muchos otros aspectos de interés al programar hubs de SignalR.
  6. Persistent connections and hubs from other threads
    En este capítulo se describen las herramientas proporcionadas por SignalR para utilizar hubs y conexiones persistentes desde hilos de ejecución externos a dicho framework.
  7. Real-time multiplatform applications
    Este capítulo está dedicado a la publicación y consumo de servicios desde servidores y clientes no web. Se describen técnicas de self-hosting en distintos entornos, y cómo implementar clientes en plataformas como Windows 8 o Windows Phone.
  8. Deploying and scaling SignalR
    En este capítulo se muestran los fundamentos de la escalabilidad de SignalR y distintas estrategias para enfrentarse a los problemas asociados al escalado de servicios. Estudiamos los backplanes incluidos de serie en el producto e incluso cómo crear backplanes propios, y finalmente, apuntamos técnicas para mejorar el rendimiento y medir el rendimiento de nuestros sistemas.
  9. Advanced topics
    Aquí tratamos temas como autorización en Hubs, extensión de SignalR, inyección de dependencias, pruebas unitarias, intercepción de mensajes e integración con otros frameworks en cliente y servidor.
En casi todos los capítulos hay ejemplos completos y multitud de porciones de código para ver de forma práctica los conceptos mostrados. Si tenéis interés, podéis ver un índice detallado en la página del libro en O’Reilly, el distribuidor oficial de libros de Microsoft Press, e incluso hay previews para hacerse una idea de lo que encontraréis dentro.

FAQ

¿Dónde puedo comprarlo? Pues básicamente donde quieras, aunque Amazon o InformIT  pueden ser buenos puntos de partida.
¿En qué formatos está disponible? El libro se comercializa en formato digital y en papel. En el primer caso, he visto que es posible obtenerlo en ePub, Mobi y PDF.
¿Va a salir el libro en español? Pues sinceramente, no lo sé. Desde luego, a corto plazo sólo estará en inglés y a día de hoy no existen planes para publicarlo en castellano, aunque no sé si esto cambiará en el futuro.

Agradecimientos

No me gustaría acabar el post sin antes agradecer al equipo de CampusMVP, con José Manuel Alarcón al frente, la oportunidad que me han brindado para poder participar en este proyecto y la fantástica gestión y ejecución del mismo. También al amigo Javier Suárez Ruíz por su imprescindible colaboración en algunos ejemplos.

Y por parte de Microsoft Press, entre muchos otros, agradecimiento infinito a Devon Musgrave por haber apostado por este proyecto desde el principio, a nuestra editora Carol Dillingham por su gran trabajo para llevarlo a cabo y a Todd Meister por sus minuciosas revisiones técnicas. Incluso hemos tenido la inmensa fortuna de contar con revisiones y comentarios de los padres de SignalR, Damian Edwards y David Fowler, a los que también envío mi agradecimiento. Todo un lujazo, vaya :)

Por mi parte, trabajar en este libro ha sido un honor y una experiencia impresionante, dura pero muy enriquecedora. Ahora espero que os sea de utilidad, que al fin y al cabo es lo que hace que el esfuerzo valga la pena :-)

Publicado en Variable not found.

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

.NET o no .NET, esa es la cuestión

Vuelta al redil y artículos publicados en otros lados

April 05, 2014 10:04 AM

Muchos de vosotros habréis supuesto que he abandonado el blog y he dejado de escribir de forma definitiva. Si bien en apariencia así, es la realidad es otra, ya que lo que no he puesto aquí lo he hecho en los blogs de la MDSN. 

Eso no quiere decir que haya abandonado esto, sino que simplemente primero publiqué allí y me olvidé de hacerlo aquí, o más bien de poner aquí una entrada que redirigiera allí.

Esta entrada soluciona eso mismo, y recoge todo lo que he publicado hasta la fecha allí y en otro blog que recientemente he abierto y que en próximos días también copiaré dichas entradas aquí.

Respecto a ese otro blog, no pretende sustituirlo, sino más bien complementarlo ya que la idea es publicar la misma cosa en paralelo en ambos, para tener algo más de visibilidad.

Bueno, comentado esto, os pongo la lista de entradas y sus enlaces.

Windows Phone, Windows 8: Portable Library y subida a la tienda: desde cero

Esta es, desde luego, la mejor entrada de todas las que he publicado allí. Como reza el título, en ella explico la creación de una aplicación sencilla tanto para Windows 8 como para Windows Phone usando la portable library y cómo subirla a las dos tiendas. Pese al tiempo transcurrido, todo sigue siendo relevante ya que pese a la unificación de las dos tiendas, el proceso de subida continua siendo igual al descrito.

Este artículo tiene su historia, ya que en origen iba a ser publicado en la revista DotNetManía pero a causa del cierre de la misma lo reutilicé allí.

Workaround para Windows Phone ListBox y LongListSelector y ScrollIntoView en elementos de diferente tamaño

 Este es un truco para hacer que el ListBox de Windows Phone 7.x se comporte como debe cuando se añaden valores de diferente tamaño y se llama a ScrollIntoView() para que se seleccione uno de ellos. Es decir, tanto Windows Phone 7 como 8 tienen un bug que ninguna actualización (hasta donde yo sé) ha resuelto: a veces no se muestra el elemento completo. Este truco mejora, aunque no solventa del todo, el problema.

Windows Phone: Subiendo un fichero a un servidor WEB con credenciales básicas sin tener que reintentar

El componente WebRequest de Windows Phone primero intenta la operación sin credenciales y cuando falla, lo hace con ellas si se han indicado. Pero eso le sienta bastante mal a algunos servidores Web, así que con este truco hacemos que el componente lo haga con ellas desde el primer momento.

El interior de Windows

Esta es una de esas entradas típicas mías que resumen o cuenta cosas que posiblemente sólo interesen a mi y a algún que otro trasnochado. Aquí hablo de Windows 8 y cómo es su arquitectura real y no la que nos muestran esos gráficos tan bonitos que hace Microsoft.

Llamando al API de WinRT desde aplicaciones de escritorio normales en C#

En este artículo describo cómo llamar al API de las aplicaciones de la tienda de Windows (las aplicaciones antes conocidas como Metro y ahora Modern UI, vamos, la de los cuadraditos de Windows 8) desde una aplicación de escritorio. La cosa queda más clara si antes de leer esta entrada, se lee la anterior de la lista.

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

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

La importancia de la comunicación

April 04, 2014 02:58 PM

Excelente artículo del PMI, lo importante que es la comunicación en las empresas y por ende en los proyectos, en los años que tengo como profesional me doy cuenta que aun en las organizaciones hay problemas básicos de comunicación y esto provoca a veces un efecto domino, agregaría que este problema de comunicación afecta varios aspectos del ser humano.

Artículo del PMI

» 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