Se permite selección múltiple 🙂

Anuncios

A colación del artículo anterior sobre TDD, he creído oportuno dedicar uno a esta metodología ágil híbrida.

La adopción de una metodología de desarrollo en una empresa de software es fundamental para el buen funcionamiento y rendimiento en el futuro.

Las eternas discusiones que surgen sobre qué o cuál modelo adoptar, como única panacea posible para el éxito, son, y siempre han sido, algo que no tiene mucho sentido. Discutir si hay que elegir entre esta o aquella metodología como si fueran antagonistas, y abanderarlas como verdad absoluta, carece de toda lógica desde el momento en que es la metodología misma la que debe adaptarse a las condiciones y características de la empresa y no al contrario. No se trata de elegir una sola manera, o quizás sí dependiendo de las necesidades de la empresa, sino de estudiar las diferentes posibilidades que nos ofrecen las distintas metodologías para aprovechar lo mejor de ellas y aplicarlas a la empresa. Es posible, ¿por qué no?, que la empresa, por su estructura o necesidades, deba asumir una metodología predictiva en vez de una ágil, a pesar de todo aquello que se ha escrito y dicho en su contra.

De la idea del estudio y colaboración entre lo mejor de distintas metodologías surge el término Scrumban, de la simbiosis entre dos metodologías denominadas ágiles: Scrum y Kanban. Aunque lo cierto es que, más que una metodología, Kanban es un marco de trabajo basado en señalizaciones. Lo mejor de ambos dan como resultado una metodología robusta y adaptable.
Scrum, hoy día, y desde hace algunos años, se erige como un buen comienzo de adaptabilidad para una empresa que desee encaminarse hacia el desarrollo ágil. Kanban, más adaptativo incluso que Scrum, se acopla perfectamente a su marco de trabajo ofreciendo un sistema de seguimiento que le asiste durante el desarrollo del product backlog y los sprints.

Para aquellos que sean neófitos en la materia, así como para otros que deseen profundizar en estas dos metodologías, os dejo unos enlaces a unos PDF interesantísimos que cubrirán todas las expectativas. En ellos, entre otras cosas, se estudia la crisis del sofware en 1968, el reinado de las metodologías predictivas, la aparición del famoso artículo en 1986 de Hirotaka Takeuchi y Ikujiro Nonaka “New New Product Development Game”, donde se ponía en duda la eficacia de las metodologías predictivas y se resaltaban los resultados de las incipientes metodologías ágiles; los pros y contras de Scrum y Kanban, la eficaz colaboración de ambos en Scrumban…etc.
Espero que los disfrutéis:

Flexibilidad con Scrum
Scrum Manager
Kanban vs Scrum

Hacer software no es una tarea sencilla. Si añadimos la necesidad de ser productivos en dicho proceso, además de escribir código reutilizable y robusto, la dificultad aumenta considerablemente.
Para enfrentarnos al problema contamos con muchas y variadas herramientas y técnicas al margen, claro está, del lenguaje de programación que vayamos a utilizar que, por supuesto, deberemos dominar sin lugar a dudas.
Una de esas técnicas de desarrollo, que ya lleva en funcionamiento muchos años con éxito, es el TDD o Test-Driven development.
Consiste en realizar los test de pruebas antes de implementar el código. Habitualmente dichas pruebas suelen realizarse después de la codificación, pero TDD nos ofrece una alternativa. Esto que puede parecer una pérdida de tiempo para muchos, no lo es si tenemos en cuenta el ahorro que nos supondrá tener un código fiable desde el principio. Esto nos evitará tener que volver a revisarlo posteriormente una y otra vez en busca de errores, bugs y demás.
Esta técnica, que ha sido aceptada en países como Estados Unidos, es casi una herejía para muchas empresas o jefes de proyecto que ven en ello un retraso en el desarrollo inmediato del software que ha solicitado el cliente. Es cierto que se requiere de una buena inversión de tiempo y recursos a corto plazo, pero nos reportará una garantía que será válida a largo plazo. Es decir, lo que hoy parece retrasarnos mañana será un avance en tiempo y costos.
Para introducirnos en este interesante tema os dejo el enlace a un libro gratuito escrito por Carlos Blé Jurado, titulado Diseño ágil con TDD.
Os aseguro que se trata de un libro fascinante que se lee apasionadamente. La explicación es llana y sencilla, acompañada a partir de la mitad del libro de un proyecto desde cero, donde se pueden ir siguiendo los pasos poco a poco para ir comprendiendo a fondo cómo debemos aplicar esta técnica, porque no se trata de hacerlo maquinalmente sino de aprehenderlo y hacerlo parte de nuestro trabajo, como una filosofía propia a la hora de desarrollar.
En definitiva un libro necesario e imprescindible.
Descargar PDF “Diseño ágil con TDD”
Descargar PDF (versión para lectores electrónicos) “Diseño ágil con TDD”

Hoy vamos a ver cómo crear un formulario web que, además de estar validado, tenga la virtud de poder ser ampliado con muy poco esfuerzo y que todas sus funcionalidades sigan en marcha.
Primero aclarar que con HTML5 los campos de tipo entrada pueden validarse automáticamente con la propiedad required (para comprobar que no estén vacíos) o, por ejemplo en el caso de un campo de entrada de email, con type=”email” poder testar que se escribe una dirección de correo correctamente. Esto está bien si supiéramos de antemano que todos nuestros visitantes usan un navegador que soporta HTML5. Pero, como sabemos, esto, desgraciadamente, no es así en más de las ocasiones de las que imaginamos. Conozco gente que todavía usa Internet Explorer 7.
Dicho esto, vamos a confeccionar este formulario a la vieja usanza, es decir, validado con JavaScript. Así que no me enrollo más y comenzamos con el código del HTML.

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
	<title>Ejemplo POO Javascript</title>
	<link rel="stylesheet" type="text/css" href="css/estilo.css"/>
</head>


<body>

	<h1>Ejemplo POO Javascript</h1>

	<fieldset><legend>Formulario POO javascript</legend>
		<form id="formulario" method="POST" action="ejemplo.php">
			Nombre *:
				<br />
				<input class="negro" name="campo" type="text" id="nombre" />
				<br/>
				<br/>
			Email *:
				<br />
				<input  class="negro" name="campo" type="text" id="email"/>
				<br/>
				<br/>
			Teléfono:
				<br />
				<input  class="negro" name="telefono" type="text" id="telefono"/>
				<br/>
				<br/>
			Comentario *:
				<br/>
				<textarea class="negro" name="campo" id="comentario" ></textarea>
				<br/>
				<br/>
			<noscript>
				<input type="submit" id="enviar" value="Enviar"/>
			</noscript>
			<button type="button" id="enviar">Enviar</button>
			<button type="reset" id="borrar">Borrar</button>
		</form>
		<br />
		<p id="mensaje"></p>
		<br />
		<progress id="progreso" max="100" value="0">Progreso</progress>
	</fieldset>
</body>

<script type="text/javascript" src="js/script.js"></script>

</html>

Como vemos se trata de un formulario que contiene cuatro campos, tres obligatorios y uno opcional. El método action del form apunta a una supuesta página de envío que, en este ejemplo, solo está a modo de test para comprobar que el formulario funciona como debe hacerlo.
Lo realmente importante de aquí son los class, name e id de los campos así como, por supuesto, sus valores. Observamos que todos los campos obligatorios tienen el mismo class y el mismo name. Los id, sin embargo, hacen alusión al objetivo de cada uno de ellos. Bien, queda claro que el llamarles así ha sido de mi elección. Tú puedes llamarlos como quieras, eso sí, respetando que se repita en todos los campos obligatorios así como tenerlo en cuenta a la hora de ser referenciados desde nuestro archivo js, el cual, cargamos al final de nuestro archivo, antes del cierre.
Fuera del formulario tenemos una etiqueta de párrafo vacía con id mensaje que usaremos para ir informando al usuario si algo no está correcto. Además hemos puesto una barra de progreso que irá indicando visualmente qué tanto por ciento correcto se ha rellenado del formulario.
También hemos indicado en el head una hoja de estilos externa que veremos más adelante.
Vamos entonces paso a paso con nuestro archivo script.js, que lo tendremos dentro de una carpeta llamada js tal y como lo hemos indicado en el HTML.

//------añadir listeners sobre el evento onblur de cada campo del formulario
//------con nombre "campo"

var elementos = document.getElementsByName("campo");

// Recorremos todos los elementos
for (var i=0; i < elementos.length; i++) {

      // Añadimos el evento onblur a cada campo del formulario con nombre "campo"
	  //llamando a la funcion crearEvento que los añade dinámicamente
      crearEvento(elementos[i], "blur");
	  
}

//Esta función es llamada desde el bucle for anterior y añade dinámicamente
//los eventos a los elementos que se le pasan como argumento. En este caso todos
//los elementos con nombre "campo"
function crearEvento(elemento, evento) {
	
	if (elemento.addEventListener) {
	elemento.addEventListener(evento, 
		function(){var lanzando = new comprobarCampo(elemento);}, false);	  
	} 
	//-----Para IE
	else {
	elemento.attachEvent("on" + evento, 
		function(){var lanzando = new comprobarCampo(elemento);});
	}
}

Lo primero que hacemos es añadir dinámicamente un evento blur a todos los elementos de nuestro formulario que tengan el nombre campo que, como ya sabemos, son aquellos campos obligatorios de nuestro formulario. Para ello primero los guardamos en un array llamado elementos, y después los recorremos llamando a la función crearEvento pasándole como argumentos tanto el mismo elemento como el evento a escuchar. Esta función es la que se encarga de hacer el trabajo dinámicamente. Observamos que dentro de esta función tenemos un condicional ya que, Internet Explorer, como siempre, hace las cosas distintas a los demás navegadores. Internet Explorer no dispone de un método addEventListener, así que debemos hacerlo con attachEvent.
Con este evento controlaremos cuándo un usuario pasa de un campo a otro dentro del formulario y llamaremos a la función comprobarCampo pasándole como argumento el propio elemento.

//clase que comprueba el contenido del campo individual que se le pasa como
//argumento
var comprobarCampo = function(campo){
		
	this.campo = campo;
		
	if (this.campo.value == ""){
			
		ponerImagen(this.campo, "error");
				
				
	}
		
	else if (this.campo.id == "email" && 
	!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(this.campo.value)))
	{
		
		ponerImagen(this.campo, "error");
				
				
	}
		
	else{
		
		ponerImagen(this.campo, "ok");
				
	}

		progreso();
		mensajes();
}

La función comprobará que el campo que se le pasa no esté vacío y que, en caso de que sea el campo que contiene el email, compruebe la sintaxis de la dirección de correo a través de una expresión regular. Vemos que, tanto si se supera la comprobación como si no, se llama a una función ponerImagen pasando como argumentos el elemento campo en cuestión y un string que indica si ha ocurrido un error o todo es ok. Además llamamos consecutivamente a las funciones progreso y mensajes. Veámoslas.

var ponerImagen = function(campo,estado){

		this.campo = campo;
		this.estado = estado;
						
		var imagen = document.createElement("img");
		imagen.className = "image";
		
		if (estado == "error"){
			
			if(this.campo.nextSibling.className == "image"){			
				borrarImagenIndividual(this.campo.nextSibling);
				imagen.src = "img/error.png";
				this.campo.className = "rojo";
				this.campo.style.border = "2px solid red";
				var padre = this.campo.parentNode
				padre.insertBefore(imagen, this.campo.nextSibling);			
			}
			else{
				imagen.src = "img/error.png";
				this.campo.className = "rojo";
				this.campo.style.border = "2px solid red";
				var padre = this.campo.parentNode
				padre.insertBefore(imagen, this.campo.nextSibling);
			}
		
		}
		else{
		
			if(this.campo.nextSibling.className == "image"){			
				borrarImagenIndividual(this.campo.nextSibling);
				imagen.src = "img/ok.png";
				this.campo.className = "verde";
				this.campo.style.border = "2px solid green";
				var padre = this.campo.parentNode
				padre.insertBefore(imagen, this.campo.nextSibling);
			}
			else{
				imagen.src = "img/ok.png";
				this.campo.className = "verde";
				this.campo.style.border = "2px solid green";
				var padre = this.campo.parentNode
				padre.insertBefore(imagen, this.campo.nextSibling);
			}
					
		}

}

Esta función crea dinámicamente una etiqueta image a la que damos un nombre de clase llamado image. Dependiendo de si el string indica error o no, usará un png de 24×24 para mostrarlo al lado del campo input correspondiente. Las imágenes son de tu elección, y están alojadas dentro de una carpeta img como puede verse en la ruta. Para comprobar si el campo disponía anteriormente de una imagen a su lado usamos this.campo.nextSibling.className == “image”. Si ya existía una la borramos con la función borrarImagenIndividual pasándole el target en cuestión. Si no había ninguna entonces le añadimos la nueva que le corresponda.
Usamos un estilo dinámico para el contorno del input. Si hay error rojo, sino verde.
El código para borrarImagenIndividual es simplemente:

var borrarImagenIndividual = function(elemento){
	
	elemento.parentElement.removeChild(elemento);

}

Sigamos con las funciones progreso y mensajes.

var progreso = function(){

	this.elementos = document.getElementsByName("campo");
	this.porcentaje = Math.round((100 / elementos.length) * Math.pow(10, 2)) / Math.pow(10, 2);
	this.barra_progreso = document.getElementById("progreso");
	this.contador = 100;
		
	// Recorremos todos los elementos
	for (var i=0; i < elementos.length; i++) {	
				
		if (elementos[i].value == ""){			
			
			contador -= porcentaje;
				
		}		
		else if (elementos[i].id == "email" 
		&& !(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(elementos[i].value))){
			
			contador -= porcentaje;
		
		}
		
		barra_progreso.value = contador;

	}	

}

La función progreso calcula dinámicamente el porcentaje de campos a rellenar en base a la cantidad de campos obligatorios del formulario. Ponemos una variable contador a 100, es decir, el total de la barra de progreso. A partir de ahí, recorriendo todos los elementos obligatorios del formulario, irá restando la variable porcentaje a la variable contador para determinar qué tanto por ciento está correctamente cumplimentado. El resultado se lo aplicamos a la barra de progreso que tenemos en nuestro HTML para que lo muestre visualmente.

var mensajes = function(){
	
	this.pMensaje = document.getElementById("mensaje");
	pMensaje.innerHTML = "";
	this.elementos = document.getElementsByName("campo");
	this.mensaje1 = "";
	this.mensaje2 = "";
	
	for (var i=0; i < elementos.length; i++) {		
		
		if (elementos[i].value == ""){			
			
			mensaje1 = "Por favor, rellene todos los campos obligatorios"; 
				
		}		
		else if (elementos[i].id == "email" && 
		!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(elementos[i].value))){
			
			mensaje2 = "Por favor, introduzca una dirección de email correcta";
		
		}

	}	

	pMensaje.innerHTML = mensaje1 + "<br />" + mensaje2;
}

La función mensajes se encargará de recorrer todos los elementos obligatorios del formulario y, en caso de error, añadir dinámicamente un texto informativo dentro de la etiqueta párrafo vacía con id mensaje que tenemos en nuestro HTML. Previamente limpiamos el contenido por si ya existiera alguno. Además, como cabe la posibilidad de que hayan varios mensajes distintos, declaramos una variable por cada comprobación y las concatenamos al final para mostrarlo.
Vamos ahora con el botón borrar de nuestro formulario:

//listener sobre el evento onclick del botón borrar formulario

if (document.getElementById("borrar").addEventListener){

	document.getElementById("borrar").addEventListener("click", function evento(){
		
		borrarTodasImagenes("image");
		
		var elementos = document.getElementsByName("campo");
		
		for (var i=0; i < elementos.length; i++) {
			
			elementos[i].className = "negro";
			elementos[i].style.border = "1px solid black";
		}

	} , true);

}
//-----Para IE
else if (document.getElementById("borrar").attachEvent){

	document.getElementById("borrar").attachEvent("onclick", function evento(){
	
		borrarTodasImagenes("image");
	
		var elementos = document.getElementsByName("campo");
		
		for (var i=0; i < elementos.length; i++) {
			
			elementos[i].className = "negro";
			elementos[i].style.border = "1px solid black";
		}
	
	});

}

Añadimos dinámicamente, como ya hicimos anteriormente, el evento click tanto para IE como para el resto de navegadores. Aparte de resetear el formulario, el botón devolverá el contorno negro a los input y se encargará de borrar todas las imágenes que hubieran de error u ok llamando a la función borrarTodasImagenes , pasando como argumento, en este caso, el nombre de clase que queremos eliminar (image).
La función borrarTodasImagenes quedaría así:

var borrarTodasImagenes = function(clase){

	this.clase = clase;

	var elementos = document.getElementsByClassName(this.clase);
	
	// Recorremos todos los elementos
	for(var k = elementos.length-1; k >= 0; --k){
		elementos[k].parentElement.removeChild(elementos[k]);
	}

}

Vamos ya con el botón enviar:

//listener sobre el evento onclick del botón enviar formulario

if (document.getElementById("enviar").addEventListener){

	document.getElementById("enviar").addEventListener("click", function evento(){
	
	var elementos = document.getElementsByName("campo");
	var lanzando = new comprobarTodo(elementos);
	
	

	} , true);

}
//-----Para IE
else if (document.getElementById("enviar").attachEvent){

	document.getElementById("enviar").attachEvent("onclick", function evento(){
	
	
	var elementos = document.getElementsByName("campo");
	var lanzando = new comprobarTodo(elementos);
	
	
	});

}

Igualmente asociamos el evento click al botón como hemos hecho hasta ahora, recuperamos todos los input obligatorios del formulario y se los pasamos como argumento a la función comprobarTodo.

//clase para comprobar todo el formulario al intentar enviarlo
var comprobarTodo = function(elementos){
	
	this.ok = true;
	this.elementos = elementos;
	borrarTodasImagenes("image");
	
	// Recorremos todos los elementos
	for (var i=0; i < elementos.length; i++) {
		
		if (elementos[i].value == ""){
			
			this.ok = false;
			ponerImagen(elementos[i], "error");
		
		
		}
		else if (elementos[i].id == "email" 
		&& !(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(elementos[i].value))){
		
			this.ok = false;
			ponerImagen(elementos[i], "error");
		
		}
		else{
		
			ponerImagen(elementos[i], "ok");
		
		}		
	  
	}

	if (this.ok == true){
	
		document.getElementById("formulario").submit();
	
	}

}

Esta última función lo que hace es recorrer todos los input obligatorios y llamar a la función ponerIMagen tanto si está rellenado correctamente como si no. En el caso de que todo esté ok, el formulario será enviado.
Para terminar veamos nuestro CSS:

img {
	padding-left: 10px;
}
input{
	height:30px;
    font-size:14pt;
}

input,textarea{
	padding:10px;
	transition: all 0.15s ease-in-out;
	border-radius:3px;
	border:1px solid rgba(0,0,0,0.2);
}
#mensaje{
	font-weight:bold;
	color:red;
	font-size:10pt;
}
        
.rojo:focus {box-shadow: 0 0 5px rgba(255,0,0,1);border:1px solid rgba(255,0,0,0.8);}
.verde:focus {box-shadow: 0 0 5px rgba(0,255,0,1);border:1px solid rgba(0,255,0,0.8);}
.negro:focus {box-shadow: 0 0 5px rgba(178,166,167,1);border:1px solid rgba(0,0,0,0.8);}


progress[value] {
/* Eliminamos la apariencia por defecto */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;

/* Quitamos el borde que aparece en Firefox */
border: none;
border-radius:5px;

/* Aplicamos las dimensiones */
width: 250px;
height: 20px;

/* Aplicamos color a la barra */
color: green;
}

/* Compatibilidad de color en Firefox y Chrome */
progress::-moz-progress-bar { background: #00A693; }
progress::-webkit-progress-value { background: #00A693; }

Lo más importante a destacar en este archivo es el aspecto personalizado que le damos a nuestra barra de progreso así como las clases rojo, verde y negro que le van a dar al input un efecto glow muy atractivo cuando el foco esté sobre él. Estas clases, si repasamos nuestro código anterior, veremos que se aplican dinámicamente cuando un campo es erróneo, cuando es ok o cuando se resetea con el botón borrar respectivamente.
Pues ya está. Terminado.
Ahora podemos añadir todos los input obligatorios que queramos a nuestro formulario, teniendo en cuenta fundamentalmente que su name debe ser campo y su class negro. De esta forma, todas las funcionalidades de nuestro código JavaScript serán aplicadas automáticamente sin hacer nada más. Bien es cierto que en este ejemplo solo tenemos en cuenta la comprobación de que el campo no esté vacío y que, en el caso de ser el campo email, sea una dirección de correo correcta, pero añadir nuevas validaciones no es nada complicado dado cómo tenemos estructurado nuestro código. Es obvio que nuestro formulario es quizás demasiado redundante en sus validaciones (imágenes, textos, barra de progreso), pero puedes adaptarlo fácilmente a tus necesidades sin demasiado esfuerzo. Además debemos tener en cuenta que por muy inteligente que sea nuestro JavaScript, debemos validarlo en el PHP destino para evitar posibles inyecciones de código no deseadas. Pero eso lo dejo para vosotros 🙂

Android Kit Kat 4.4 ya está aquí

Publicado: febrero 7, PM en Enlaces, Noticias
Etiquetas:,

Como lo prometido es deuda vamos a ver, resumidas, las novedades que nos trae esta nueva versión del pequeño, pero enorme, robot verde.
Lo nuevo que nos aporta Kit Kat 4.4 no solo es a nivel de experiencia de usuario sino, por supuesto, también a nivel de desarrollo. Todo está preparado para dar un salto cualitativo en las funcionalidades de los dispositivos que ya disfrutan, a fecha de hoy, de sus excelencias, como pueden ser el Samsung Galaxy s4, HTC One, Nexus 4, 7 o 10 entre otros muchos que estarán disponibles en un breve lapso de tiempo.
Sin más veamos cuáles son algunas de esas novedades:

1) LAUNCHER RENOVADO: Google Now se incorpora a la pantalla de inicio totalmente mejorada y con nuevas opciones. Los iconos son ahora algo más grandes y algunos han sido rediseñados para que se vean mejor. La barra de notificaciones es ahora transparente lo que permite que el fondo de pantalla se extienda por toda la superficie dando lugar a una estética mejorada.

2) MEJORAS INTERNAS: La multitarea es ahora más veloz que nunca. Las aplicaciones en segundo plano consumen menos memoria. Con Chromium WebView se facilita a los desarrolladores una manera más sencilla de generar y mostrar contenido basado en internet. Se incluye más soporte HTML5, CSS3 y JavaScript. El sistema ha sido diseñado para adaptarse perfectamente tanto a dispositivos de gama baja como de gama alta. Todas las aplicaciones y funcionalidades de la versión han sido rediseñadas para lograrlo. Nuevo soporte NFC. Sistema inteligente de reproducción de video adaptativa que alterna entre resoluciones en base a la conexión WIFI para conseguir la mejor opción de visionado.

3) LA NUBE: Función Cloud Print incorporada. Google drive permite el acceso a sus carpetas a través de aplicaciones como QuickOffice.

4) MAIL: Actualizado con nuevos gestos y opciones para gestionar los correos.

5) APP TELÉFONO: Se identifica a los números de las llamadas recibidas y realizadas comparándolas con los de las empresas. De esta forma se pueden evitar llamadas comerciales no deseadas. Importación y exportación de contactos desde la tarjeta SD o desde una cuenta en la nube. Los contactos pueden ser ordenados en grupos y categorías.

6) APP MENSAJES SMS: Desaparece. Ahora los mensajes se envían a través de Google Now.

7) GOOGLE+ FOTOS: Nueva aplicación para editar, cargar y compartir imágenes. Dispone de un potente paquete de herramientas de edición de imágenes como por ejemplo poder crear una película uniendo varias fotos. Igualmente están disponibles un sinfín de filtros.

8) HDR+ FOTOS: Trabaja junto a la App Google+ Fotos y permite tomar imágenes espectaculares. Se accede a través de la App Cámara y usa una opción al estilo ráfaga que reconstruye y elige el mejor disparo de una amplia gama de imágenes.

9) INTERFAZ INTELIGENTE: Opción pantalla completa al leer un libro o ver un vídeo. Se muestra la portada del álbum o la película que se esté viendo como pantalla de bloqueo mientras se hace streaming a otro dispositivo. Nueva App de descargas con nuevas funcionalidades que facilitan el seguimiento. Notificaciones renovadas más atractivas y que se pueden usar con otras apps.

Bueno, hecho este repaso a lo más importante solo me queda dejar un enlace a las novedades que presenta esta versión desde el punto de vista del desarrollador:
Developer Android Kit Kat
Espero que os haya gustado y que fomente vuestro interés por este nuevo paso en la carrera del gigante Android.

La disputa sobre qué sistema operativo para dispositivos móviles es mejor siempre me ha parecido un tanto maniquea. Todos tienen su pro y su contra, como casi todo en la vida. Ser un fanático de uno de ellos creo que no es razonable porque los fanatismos son el árbol que no te deja ver el bosque. Pero si me tuviera que decantar por uno hoy día, ahora mismo, diría sin lugar a dudas que prefiero Android. ¿Por qué?. Pues porque es flexible, código abierto, porque ha demostrado que mejora día a día en cada nueva actualización o versión, porque es sencillo, potente, amigable y muchas otras cosas más. Pero sobre todo porque las aplicaciones se programan en Java (una variación llamada Dalvik), un lenguaje multiplataforma y uno de los de mi devoción. Para ser honestos la verdad es que a Android le quedan muchas cosas por limar, sobre todo en lo que respecta a la seguridad. Google Play sigue manteniendo a día de hoy un agujero muy difícil de tapar dada la enorme cantidad de aplicaciones que mantiene. Estoy seguro que tarde o temprano se resolverá pero, desde luego, es un hándicap muy peliagudo. Sin embargo, Android 4.4 Kit Kat ya está aquí para hacer las delicias de los que apostamos por este sistema. En breve espero hacer un repaso de las novedades que nos ofrecerá esta nueva versión del robot verde.
¿Por qué no iOS? Desde luego se trata de un sistema de una robustez incontestable, de un acabado casi perfecto, de una potencia sin igual. Un sistema a prueba de balas. Pero lo que no me convence es, entre otras cosas y resumiendo, que tenga que usar un lenguaje propietario como Objective C & Cocoa. Vale que existen herramientas como Corona SDK y Lua para ponernos las cosas más fáciles, pero aún así no me gusta ese mundo cerrado y arisco con todo lo que sea distinto.
En cuanto a Windows Phone 8 ¿Por qué no? Cierto es que los de Redmond han hecho un trabajo excelente pese a las críticas que ha recibido su nueva versión. Su interfaz y su usabilidad no pueden dejar a nadie indiferente. Hablamos de una filosofía de aplicaciones interconectadas entre sí que es abrumadora. Es verdad que las cifras que se esperaban, en cuanto a dispositivos que utilizarían este sistema no ha cubierto las expectativas, pero no por ello debemos echarlo por tierra cuando demuestra tener un futuro prometedor si continúan así. Lo malo es que para poder desarrollar aplicaciones para la Windows Store, sí o sí debes tener instalado Windows 8. Y si además quieres programar nuevas funcionalidades solo están disponibles si lo haces desde Windows 8.1, su última actualización hasta la fecha. No me convence esta forma de obligar al programador a pasar por taquilla.
En fin, ya solo quedas tú y tu opinión. Por supuesto puedes elegir cualquier otro sistema distinto a los tres expuestos. Adelante.

Decorator Patrón de diseño

Decorator Patrón de diseño

Los patrones de diseño son esenciales en el desarrollo de software. La famosa banda de los cuatro formada por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides es toda una referencia en el campo del diseño orientado a objetos. No solo basta con el conocimiento de los patrones sino saber cómo y cuándo emplearlos. Como sabemos, no existen para complicar la vida del programador, sino todo lo contrario. Se intenta garantizar con ellos la efectividad en la resolución de problemas comunes en todo desarrollo de software complejo así como la reusabilidad de los mismos en futuros proyectos. Es evidente que se trata de un tema con enjundia que conviene siempre tener a mano. Por ello voy a dejaros un enlace al canal de youtube de Alexys Lozada, un muchacho que ha realizado un excelente trabajo sobre patrones de diseño y que muestra, con sus videotutoriales de ejemplo, nada menos que 19 de ellos usando Java como lenguaje de programación.
Además, en el canal podréis encontraros, siempre dentro del mundo de Java, con otros temas tan interesantes como la recursividad, manejo de excepciones y estructura de datos.
Imprescindible.
http://www.youtube.com/user/Alexyslozada
Los códigos de los videotutoriales pueden obtenerse desde aquí:
https://github.com/alexyslozada/CursoPatronesDiseno