Autor en Google+
Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

15 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
domingo, 22 de marzo de 2009

Windows Live Writer Aunque lamentablemente no me haya dado  demasiada prisa en hacerlo, tenía ganas de probar este producto. Si habéis utilizado alguna vez el interfaz de edición de Blogger, sabréis que no es precisamente una maravilla, y que a veces complica bastante la publicación de entradas en el blog, y máxime cuando se trata de contenidos con formatos especiales, como puede ser código fuente en cualquier lenguaje.

Live Writer es una fantástica aplicación de escritorio desarrollada por Microsoft en el contexto de su iniciativa Live, cuyo objetivo es facilitar la edición y publicación de entradas en blogs y, lo más curioso, compatible con los motores más difundidos del mercado: Blogger, WordPress, LiveSpaces, LiveJournal, TypePad, y un largo etcétera. Y cuando digo compatible, al menos con Blogger, me refiero a realmente compatible, una integración casi perfecta, que hace que la edición de entradas sea una gozada.

Previsualización de la entradaDurante la instalación, Writer nos solicita la introducción de los datos de acceso al blog: la dirección, el usuario y clave. Con esta información, y por supuesto previa confirmación por parte del usuario, crea automáticamente una entrada temporal en el blog que utiliza para tomarla como plantilla, eliminándola unos segundos después. De esta forma, cuando estamos escribiendo, podemos acceder a una previsualización del contenido insertada en sobre dicha plantilla, que nos dará una idea muy aproximada, prácticamente real, del resultado final que obtendremos una vez publiquemos la entrada.

El editor sobre el que escribimos es muy ligero, tiene las opciones justas para poder escribir y dar formato a los textos, siempre de forma visual (el famoso WYSIWYG). Aunque a primera vista puede parecer que se quedará corto, nada más lejos de la realidad; no he echado en falta prácticamente ninguna característica que realmente pudiera hacerme falta durante la escritura: formatos estándar (negritas-cursivas-tachados, subrayados), colores, tablas, alineados, listas, citas,… y siempre generando un código XHTML realmente limpio y muy bien estructurado, a diferencia de otros editores basados en web (como el de Blogger, por ejemplo).

Sólo en casos especiales (por ejemplo, la inclusión de una etiqueta <acronym> para mostrar ayuda sobre el significado de WYSIWYG, o la inclusión de código fuente marcado con <code> son los únicos casos en los que he tenido que salirme del editor visual y acceder a la vista de código fuente XHTML para introducir las etiquetas.

Otro aspecto muy importante es su extensibilidad. Existen un gran número de complementos que pueden instalarse sobre este software para dotarlo de nuevas capacidades no contempladas en el producto base. Por aunque la galería de complementos de Microsoft todavía está a cero no está muy transitada, es fácil encontrar muchos sitios web donde se ofrecen plugins de todo tipo. Por ejemplo, he encontrado uno que a priori puede resultar muy útil, Steve’s Dunn Code Formatter, que permite incluir fácilmente porciones de código formateadas como la siguiente:

try
{
calculate();
// Hard work!
}
catch (Exception ex)
{
Logger.Log(ex.Message);
throw;
}


Pero lo que sin duda más ha llamado mi atención es la gran facilidad para insertar contenidos multimedia, como álbumes de fotos, vídeos, mapas interactivos, y especialmente imágenes, que es lo que más suelo utilizar en mis posts. En este último caso, es sorprendentemente útil la capacidad de Live Writer para abrir imágenes del equipo local o pegarlas directamente desde el portapapeles (por ejemplo capturas de pantalla), ajustarlas al tamaño indicado e incluso agregarle sobre la marcha efectos como sombreados o reflejos (podéis ver ejemplos más arriba). Por fin se acabó el retoque con aplicaciones externas, tener que subir la imagen al servidor, ver cómo queda, retocarla de nuevo, volver a subirla…

Por último, el hecho de tratarse de una herramienta off-line aporta mucha agilidad, y nos brinda la posibilidad de trabajar en modo desconectado, aunque a costa de perder algunas funcionalidades para las que obviamente es necesario disponer de conexión a internet, como la edición de posts ya publicados, almacenados en el blog, o el envío directo de las entradas. En estos casos, el sistema almacena toda la información en local, para que más adelante podamos enviar los cambios realizados.

Ni que decir tiene que este post está completamente escrito sobre Live Writer, e incluso las imágenes las he generado desde la propia herramienta.

En resumen: una maravilla, imprescindible.

Descarga: Microsoft Live Writer

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 1 de marzo de 2009
PuzzleEs bastante habitual encontrar código que captura una excepción y la vuelve a relanzar tras realizar algún tipo de operación. Sin embargo, habréis observado que existen varias fórmulas para hacerlo, y no necesariamente equivalentes:
  • crear y lanzar una nueva excepción partiendo de la original
  • relanzar la excepción original
  • dejar que la excepción original siga su camino
El primer caso ocurre cuando capturamos una excepción de un tipo determinado, y desde dentro del mismo bloque catch instanciamos y lanzamos otra excepción distinta a la original. Esto permite elevar excepciones a niveles superiores del sistema con la abstracción que necesita, ocultando detalles innecesarios y con una semántica más apropiada para su dominio.

El siguiente ejemplo muestra una porción de código donde se están controlando distintos errores que pueden darse a la hora de realizar una transmisión de datos. Por cada uno de ellos se llevan a cabo tareas específicas, pero se elevan al nivel superior de forma más genérica, como TransmissionException, pues éste sólo necesita conocer que hubo un error en la transmisión, independientemente del problema concreto:
  ...
try
{
transmitir(datos);
}
catch (HostNotFoundException ex)
{
sendToAdmin(ex.Message); // Avisa al administrador
throw new TransmissionException("Host no encontrado", ex);
}
catch (TimeOutException ex)
{
increaseTimeOutValue(); // Ajusta el timeout para próximos envíos
throw new TransmissionException("Fuera de tiempo", ex);
}
...
 
Es importante, en este caso, incluir la excepción original en la excepción lanzada, para lo que debemos llenar la propiedad InnerException (en el ejemplo anterior es el segundo parámetro del constructor). De esta forma, si niveles superiores quieren indagar sobre el origen concreto del problema, podrán hacerlo a través de ella.

Otra posibilidad que tenemos es relanzar la misma excepción que nos ha llegado. Se trata de un mecanismo de uso muy frecuente, utilizado cuando deseamos realizar ciertas tareas locales, y elevar a niveles superiores la misma excepción. Siguiendo con el ejemplo anterior sería algo como:
  ...
try
{
transmitir(datos);
}
catch (HostNotFoundException ex)
{
sendToAdmin(ex.Message); // Avisa al administrador
throw ex;
}
...
 
Este modelo es conceptualmente correcto si la excepción que hemos capturado tiene sentido más allá del nivel actual, aunque estamos perdiendo una información que puede ser muy valiosa a la hora de depurar: la traza de ejecución, o lo que es lo mismo, información sobre el punto concreto donde se ha generado la excepción.

Si en otro nivel superior de la aplicación se capturara esta excepción, o se examina desde el depurador, la propiedad StackTrace de la misma indicaría el punto donde ésta ha sido lanzada (el código anterior), pero no donde se ha producido el problema original, en el interior del método transmitir(). Además, a diferencia del primer caso tratado, como la propiedad InnerException no está establecida no será posible conocer el punto exacto donde se lanzó la excepción inicial, lo que seguramente hará la depuración algo más ardua.

La forma de solucionar este inconveniente es utilizar el tercer método de los enumerados al principio del post: dejar que la excepción original siga su camino, conservando los valores originales de la traza:
  ...
try
{
transmitir(datos);
}
catch (HostNotFoundException ex)
{
sendToAdmin(ex.Message); // Avisa al administrador
throw;// Eleva la excepción al siguiente nivel
}
...
 
En esta ocasión, si se produce la excepción HostNotFoundException, los niveles superiores podrán examinar su propiedad StackTrace para conocer el origen concreto del problema.

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 22 de febrero de 2009
C#La palabra reservada using tiene diversos usos en el lenguaje C#, y seguro que muchos la utilizamos exclusivamente para importar espacios de nombres (namespaces), ignorando el resto de posibilidades que nos ofrece:
Vamos a dar un repasillo a cada una de estas utilidades, profundizando un poco en aquellas menos habituales.

1. Importación de espacios de nombres

En este caso, la palabra reservada using actúa como una directiva del compilador, haciendo que se puedan utilizar tipos definidos en el espacio de nombres importado sin necesidad de especificarlos de forma explícita en el código.
  using System;
using System.Collections;...
 
Este es el using más común y conocido, así que poco más hay que decir al respecto...

2. Definición de alias

Otra forma de utilizar using como directiva es crear alias, o nombres cortos alternativos, a namespaces o tipos de datos, que ayuden a evitar conflictos en nombres. Veamos cada uno de ellos.

2.1. Alias de espacios de nombres

Puede ser útil cuando tenemos namespaces cuyos nombres coinciden con el de clases, o en situaciones similares que hacen que el compilador no tenga claro qué estamos intentando decirle. Por ejemplo, observad el siguiente código, que no compila, a pesar de ser aparentemente correcto:
  using System;
namespace Prueba
{
class Saludo
{
public static void Run()
{
Console.WriteLine("hola");
}
}
}

namespace OtroNS
{
class Prueba
{
public static void Main(string[] args)
{
Prueba.Saludo.Run(); // No compila
Console.ReadLine();
}
}
}
 
El problema es que para acceder a clase que queremos utilizar (Saludo) desde un namespace distinto a donde se encuentra definida debemos indicar su ruta completa, es decir, especificar en qué espacio de nombres la encontraremos. Sin embargo, en el ámbito de la clase Prueba, el compilador piensa que el código Prueba.Saludo.Run() está intentando acceder a una propiedad de dicha clase, y como no lo encuentra, revienta en compilación.

La solución a esto es bien sencilla utilizando los alias, puesto que permiten hacer referencia a un espacio de nombres o un tipo utilizando una denominación diferente, lo que eliminará la ambigüedad. Podemos, por ejemplo, utilizar el alias predefinido global, que representa al nivel raíz del árbol de namespaces:
      ...
public static void Main(string[] args)
{
global::Prueba.Saludo.Run();
Console.ReadLine();
}
...
 
Otra posibilidad, usando using, sería definir un alias personalizado que nos permitiera acceder al espacio de nombres conflictivo utilizando otro identificador:
  ...
using MiAlias = Prueba;
...
....
public static void Main(string[] args)
{
MiAlias::Prueba.Saludo.Run();
Console.ReadLine();
}
...
 
Observad el uso de los dos puntos (::) para indicar que el identificador que se encuentra a su izquierda es un alias. Esto puede ayudar a evitar conflictos cuando el nombre del alias coincida con el de una clase en el ámbito de visibilidad actual.

2.2. Alias a tipos

De la misma forma, podemos crear fácilmente alias a un tipo definido, bien para evitar conflictos en nombres como los descritos anteriormente, o bien para hacer más rápido el acceso a los mismos. En el siguiente ejemplo puede observarse su uso:
  using Strings = System.Collections.Specialized.StringCollection;
using Con = System.Console;
...
Strings s = new Strings(); // 's' es un StringCollection
Con.WriteLine("hola");
 
Habréis observado que en este caso no se utilizan los dos puntos (::) para separar el alias del resto, puesto que éste no representa a un namespace, sino a un tipo.

3. Adquisición y liberación de recursos

En este caso, using sirve para especificar bloques de código en los que se van a utilizar recursos que deben ser liberados obligatoriamente al finalizar, como podrían ser conexiones a base de datos, manejadores de ficheros, o recursos del propio sistema operativo. De hecho, salvo en contadas ocasiones, utilizar using es la forma más recomendable de tratar estos asuntos.

En un bloque using se definen una serie de recursos, siempre implementando la interfaz IDisposable, y se delimita un bloque de código en el que éstos serán válidos y visibles. Al salir la ejecución de dicho bloque, estos recursos serán automáticamente liberados llamando a sus respectivos métodos Dispose(). Y esto se hará siempre, independientemente de si la salida del bloque ha sido de forma natural, mediante una excepción o un salto. En otras palabras, el compilador nos asegura que siempre invocará el método Dispose() de todos los recursos comprometidos en la operación.

Un ejemplo muy habitual lo vemos con las conexiones de bases de datos, recurso valioso donde los haya. La forma correcta de tratarlas sería:
  using (SqlConnection conn = new SqlConnection(connectionString)) 
{
hacerAlgoConLosDatos(conn);
}
// Al llegar aquí, la conexión está liberada. Seguro.
// Además, la variable conn no es visible.
 
Respecto a la liberación automática de recursos, no hay nada mágico en ello. Internamente, el compilador de C# está transformando el código anterior en:
  SqlConnection conn = new SqlConnection(connectionString);
try
{
hacerAlgoConLosDatos(conn);
}
finally
{
if (conn != null)
((IDisposable)conn).Dispose();
}
 
Además de asegurar que los recursos son liberados cuando ya no van a ser necesarios, tiene también un efecto positivo al hacer que centremos su uso en un bloque compacto, fuera del cual no se podrá acceder a los mismos; por ejemplo, en el caso anterior, dado que la variable conn no es visible desde fuera del bloque using, evitaremos accesos a ella cuando haya sido liberada, que provocaría errores en tiempo de ejecución.

Y por cierto, una posibilidad interesante y no demasiado conocida es que se pueden especificar varios recursos en el mismo bloque using, de forma que todos ellos se liberen al salir, sin necesidad de tener que anidarlos, siempre que sean del mismo tipo, por ejemplo:

// Anidando usings
using (SqlConnection conn1 = new SqlConnection(connstr1))
{
using (SqlConnection conn2 = new SqlConnection(connstr2))
{
// hacer algo con las dos bases de datos
}
}

// Forma más compacta
using (SqlConnection conn1 = new SqlConnection(connstr1),
conn2 = new SqlConnection(connstr2))
{
// hacer algo con las dos bases de datos
}
 

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

lunes, 16 de febrero de 2009
Google CodeUna posibilidad interesante que ofrece Google a los desarrolladores es utilizarlo como CDN (red de difusión de contenidos) para las librerías javascript open source más populares. En la práctica, esto quiere decir es que en tus desarrollos web, en lugar de subir a tu servidor las librerías que utilices para scripting, puedes referenciar y usar directamente las que te ofrece esta compañía en sus servidores.

Esto aporta varias ventajas nada despreciables:
  • primero, la descarga de estas librerías será, para el cliente, probablemente más rápida que si las tiene que obtener desde tu servidor a través de internet. Se trata de infraestructura de red de Google, y eso implica unas garantías.

  • segundo, y relacionada con la anterior, si se trata de un sitio web de alto tráfico, la concurrencia permitida seguramente será infinitamente mayor que la que puedas ofrecer en otro servidor.

  • tercero, si el usuario ha visitado previamente otro sitio web que use también la misma librería, se beneficiará del cacheado local de la misma, puesto que su navegador no la descargaría de nuevo. Y en cualquier caso, se estarían aprovechando las optimizaciones de caché de Google.

  • cuarto, no consumes ancho de banda de tu proveedor, aunque éste sea despreciable. Y con despreciable me refiero al ancho de banda, no al proveedor ;-)

  • quinto, puedes utilizar las librerías desde webs alojadas en algún sitio donde no se pueda, o no sea sencillo, subir archivos de scripts, como la plataforma Blogger desde la que escribo.

En este momento se contemplan los siguientes frameworks, en todas las versiones disponibles:
  • jQuery
  • jQuery UI
  • Prototype
  • script_aculo_us
  • MooTools
  • Dojo
  • SWFObject
  • Yahoo! User Interface Library (YUI)

Si ya estás utilizando librerías Ajax de Google (como el API de visualización, o el de Google Maps), y las obtienes mediante el cargador google.load(), también puedes utilizarlo para descargar estos frameworks. Asimismo, puedes hacerlo mediante una referencia directa, del tipo:

<script
src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
</script>
 
Ah, y no hay que preocuparse por los cambios de versiones, ni nada parecido. Google se compromete a alojar indefinidamente todas las distribuciones que vayan publicando, así como de incluir actualizaciones conforme aparezcan.

Por último, y para aportar una visión negativa, hay quien opina que se trata de una estrategia más de Google para obtener información sobre la navegación de los usuarios; la ejecución de código procedente de sus servidores posibilitaría la lectura de cookies y datos que podrían ser utilizados para fines distintos de los previstos en tu web. También hay quienes piensan que podría ser una fuente de difusión de código malicioso si alguien consiguiera hackear estos repositorios. Obviamente, tampoco es buena idea utilizar esta opción si vas a trabajar en modo local, sin conexión.

Para más información sobre las formas de descarga y las librerías disponibles, puedes visitar la guía del desarrollador de las Ajax libraries API.


Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 8 de febrero de 2009
HundimientoMe he vuelto a encontrar con el divertido post 101 Ways To Know Your Software Project Is Doomed, donde se enumeran 101 pistas que te ayudarán a saber si tu proyecto está condenado a fracasar estrepitosamente. Tras contactar con Max Pool, el propietario del blog Codesqueeze, me ha permitido muy amablemente publicar aquí una traducción de su post completo.
  1. La dirección ha cambiado el nombre del "procedimiento en cascada" por "cascada ágil".
  2. Se han empezado a contratar consultores para poder echarles las culpas de todo.
  3. El servidor de integración continua retorna el error "Que te jodan. Me largo".
  4. Habéis implementado vuestro propio framework en Ruby que usa archivos de configuración XML.
  5. El miembro del equipo más mayor se refiere a Martin Fowler como "ese gamberro engreído".
  6. Vuestro sistema de control de código fuente consiste en una serie de carpetas en un disco compartido en red.
  7. El tiempo asignado para QA es destinado a preguntarse el por qué de ese desastre.
  8. Todos los requisitos están escritos en una servilleta de papel.
  9. Empiezas a considerar un cambio de empleo para no tener que mantener la aplicación que estás desarrollando.
  10. El responsable de desarrollo web piensa que la X de XHTML viene de "eXtremo".
  11. Las reuniones de todas las iteraciones comienzan por un "¿prefieres las buenas o las malas noticias?".
  12. El equipo todavía considera que su nivel de CMM es una mierda.
  13. El progreso se mide por el número de errores corregidos, y no por funcionalidades o características finalizadas.
  14. La integración continua está haciendo que los empleados nuevos lean el manual del empleado.
  15. Eres amigo del portero.
  16. Al SCRUM master no le importa lo que hicisteis ayer, ni lo que haréis hoy.
  17. Cada hito acaba en un sprint mortal.
  18. Vuestro mejor desarrollador lo único que tiene es su expediente académico brillante.
  19. No entendéis los acrónimos DRY, YAGNI o KISS, pero sí WTF, PHB o FUBAR.
  20. El jefe podría ser sustituido por un script de redirección de emails.
  21. La única certificación de vuestros procesos de construcción de software es la ISO 9001/2000.
  22. El jefe piensa que "métrica" es un tipo de bebida proteínica.
  23. Todos los errores son priorizados como críticos.
  24. Todas las funcionalidades son priorizadas como triviales.
  25. Las estimaciones económicas del proyecto mágicamente coinciden con el presupuesto disponible para el mismo.
  26. Los desarrolladores usan la excusa del código autodocumentado para justificar la ausencia de comentarios.
  27. Vuestro patrón favorito es el god object.
  28. Todavía pensáis que compilar es una forma de testear.
  29. Los desarrolladores todavía utilizan Notepad como entorno de desarrollo.
  30. El gestor del proyecto pasa 7 horas a la semana pidiendo informes de progreso (basado en hechos reales).
  31. No tenéis máquina propia, y no estáis programando por parejas.
  32. Norma del equipo: no hay reuniones hasta las 10:00am, puesto que ayer estuvimos aquí hasta las 2:00am.
  33. En el equipo se piensa que los ORM son una moda.
  34. El equipo piensa que la transición desde VB6 a VB.NET será sencilla.
  35. El gestor piensa que MS Project es la mejor herramienta de gestión de proyectos del mercado.
  36. Tu esposa sólo consigue verte en una webcam.
  37. Ninguno de test unitarios tienen aserciones (asserts).
  38. Vuestro editor de páginas favorito es FrontPage.
  39. Se discute encendidamente sobre si la llave "{" debe escribirse en una nueva línea, pero se es impacial ante el uso de patrones como MVC.
  40. El lema de la compañía es "haz más con menos".
  41. La frase "funciona en mi máquina" se escucha más de una vez al día.
  42. La última conferencia a la que asistió el equipo de desarrollo .NET fue la Apple Worldwide Developers Conference 2000.
  43. Los gestores insiten en registrar toda la actividad, pero nunca usan esa información para tomar decisiones.
  44. Toda la depuración se hace en el servidor en producción.
  45. El jefe no sabe cómo comprobar el email.
  46. El jefe piensa que ser compatible SOX significa no trabajar las noches en las que hay béisbol.
  47. La empresa contrata al senador Ted Stevens para la charla de inicio del proyecto.
  48. El último libro que leíste fue la Biblia de Visual Interdev 6.
  49. El presupuesto general se confunde con tu gasto semanal en Mountain Dew.
  50. El jefe se pasa la hora de la comida llorando en el coche (otro hecho real).
  51. El responsable de desarrollo web define Ajax como un producto de limpieza.
  52. Tu jefe espera que pases los dos próximos días creando una solicitud de compra por un componente de 50$.
  53. El equipo de ventas reduce tus estimaciones porque creen que podéis trabajar más rápidamente.
  54. Requisito - Rank #1 en Google.
  55. Todos los días trabajas hasta medianoche, y tu jefe se va a las 16:30.
  56. A los jefes les encanta decir: "¿por qué se preocupan los desarrolladores? Cobran por horas".
  57. El personal del turno de noche de StarBucks te conoce por tu nombre.
  58. El jefe no pueden entender por qué alguien puede necesitar más de un monitor.
  59. El equipo de desarrollo sólo usa el control de código fuente como sistema de backup por si falla el suministro eléctrico.
  60. Los desarrolladores no son responsables de realizar ninguna prueba.
  61. El equipo no usa SVN porque piensan que los algoritmos de fusión (merge) son pura magia negra.
  62. Tus pizarras no tienen nada escrito (Version One).
  63. El cliente confunde siempre tu gráfico burn-down con un burn-up (lo que queda por hacer con lo que está hecho).
  64. El nombre clave del proyecto pasa a ser "Marcha de la muerte".
  65. Te duele físicamente decir la palabra "sí".
  66. Tus compañeros no refactorizan, sino refuctorizan.
  67. Como recompensa por el tiempo extra, tu jefe compra una nueva cafetera.
  68. El presupuesto de tu proyecto se contabiliza en la empresa como gastos estructurales.
  69. Puedes bloguear desde el trabajo, gracias a que subcontratas porciones del proyecto.
  70. Se crea un comité de control de cambios del proyecto, incluso antes de disponer de la primera versión alfa.
  71. Diariamente consideras romperte los dedos para estar impedido un tiempo.
  72. El hito final de entrega ha sido renombrado simplemente como "hito", igual que el anterior.
  73. La política de puertas abiertas de la dirección sólo se aplica desde las 17:00 hasta las 8:00 horas.
  74. La dirección opina que "por qué comprarlo cuando podemos construirlo".
  75. Traes cerveza a la oficina durante el segundo turno.
  76. Descubrís al director del proyecto consultando una tabla Ouija.
  77. Das información errónea sobre tus compañeros de trabajo para parecer mejor en tu revisión personal.
  78. Las revisiones de código se planifican para una semana antes del lanzamiento del producto.
  79. Sólo existe presupuesto para realizar pruebas "si tenemos tiempo".
  80. El cliente sólo habla sobre los requisitos cuando ya tiene una estimación fija.
  81. Tu jefe no le encuentra la gracia a Dilbert.
  82. Comienzas a notar los faroles del jefe durante un planning poker.
  83. Empiezas a pensar si trabajar dos turnos en Pizza Hut sería una mejor alternativa para tu carrera profesional.
  84. Todos los problemas de rendimiento se solucionan poniendo máquinas más potentes.
  85. El proyecto va a ser lanzado como una versión beta permanente.
  86. Se llevan tu coche del parking por pensar que estaba abandonado.
  87. El jefe de proyecto suele garabatear durante las reuniones de toma de requisitos.
  88. Estás utilizando MOSS 2007.
  89. Tu equipo SCRUM consiste en una única persona.
  90. Tu hoja de control de horas parece un ticket de Powerball.
  91. El desarrollador web piensa que 508 tiene que ver con sus pantalones Levi's.
  92. Piensas que necesitas medicación para la personalidad múltiple porque eres Mort, Elvis, and Einstein al mismo tiempo.
  93. Tu jefe sustituye el asesoramiento profesional de un consultor por una bola mágica.
  94. Sabes exactamente cuántos warnings en compilación provocan que tu IDE genere una excepción de "fuera de memoria".
  95. A estas alturas, todavía no sabes a qué me refiero con el término "IDE".
  96. Has copiado y pegado código desde The Daily WTF.
  97. Los tests unitarios que fallan son eliminados porque, obviamente, están obsoletos.
  98. Eres enviado a una conferencia a aprender, pero te saltas las sesiones para ir a ver si pillas algo.
  99. El personal de QA te apoda "Jefe Off-by-one".
  100. Tenéis el 90% del software completo el 90% del tiempo.
  101. "Oh, oh, casi se me olvida. Ah, voy a necesitar que vengáis también este domingo... gracias".


Post original: 101 Ways To Know Your Software Project Is Doomed
Publicado en: Variable not found

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

domingo, 1 de febrero de 2009
Borrar... borrar...Cuando me topé por primera vez con el término NNPP (siglas de "Net Negative Producing Programmer") no puedo negar que me hizo cierta gracia. Cuanto menos, resultaba curioso pensar que podían existir desarrolladores cuyo saldo en las aportaciones a un proyecto resultara negativo, o lo que es lo mismo, que el valor de su producción fuera superado por el coste de los errores y defectos que introducían en las aplicaciones. Y con el término "desarrolladores" no me refiero exclusivamente a programadores; el concepto es válido para analistas, arquitectos, testers, o cualquier otro rol relacionado con la construcción de software.

Aunque seguro que todos hemos trabajado con profesionales que consideramos desastrosos poco habilidosos en la ejecución de sus tareas, probablemente no hayamos reflexionado lo suficiente sobre el impacto que tiene esto en un proyecto, y el coste final que clientes, nuestra empresa, o nosotros mismos tenemos que asumir en muchos casos. Es en este momento cuanto la existencia de NNPPs deja de tener gracia.

Y eso mismo debió pensar G. Gordon Schulmeyer cuando escribió, a principio de los 90, el paper "The Net Negative Producing Programmer" para la publicación American Programmer (hoy en día Cutter IT Journal), en el que se describía detalladamente qué son los NNPPs, cómo podemos reconocerlos, los motivos de su existencia, y los posibles remedios a aplicar cuando se detectan en un equipo de trabajo.

Según se manifiesta en este documento, los NNPP no son casos extremos. De hecho, en un equipo de diez desarrolladores pueden existir desde uno hasta tres NNPP, lo cual no es ninguna tontería: entre el 10 y el 30% del equipo de trabajo podría estar contribuyendo de forma negativa al éxito del proyecto. En otras palabras, en lugar de desarrollar estarían desdesarrollando, si me permite el amigo Andrés Panitsch que le tome prestado brevemente el nombre de su genial blog.

Aunque pueda parecer lo contrario, la detección objetiva de los programadores con producción neta negativa no es sencilla. Schulmeyer propone la utilización de un modelo de comportamiento donde se evalúen, al menos, las habilidades para:
  • escribir un programa
  • encontrar y depurar errores
  • ampliar un software para adaptarlo a nuevas necesidades
  • adquirir nuevos conocimientos técnicos
  • comprender un determinado problema

Salvo el último punto, de ámbito más abstracto, existen métricas que ayudan a determinar hacia dónde se inclina la balanza cuando comparamos la productividad de un desarrollador con su ratio de introducción de defectos en el software. Sin embargo, además de los aspectos técnicos, existen impedimentos éticos, y a veces incluso legales, que impedirían la obtención de conclusiones directas a partir de registros de actividad.

Pero probablemente, para poder detectar y evitar la aparición o proliferación de NNPPs en las organizaciones es importante conocer las causas de su existencia. Un estudio citado en el artículo revela causas como la insatisfacción en el trabajo, identificación e implicación nulas con el proyecto, percepción de escasa relación entre profesionalidad y recompensa, y falta de profesionalidad. Es obvio que, transcurridos quince años, siguen siendo válidas hoy en día; y curioso que muchas de ellas sean más atribuibles a la compañía y sus gestores que a los propios profesionales sospechosos de producir en negativo, normalmente por utilizar políticas restrictivas, estresantes, opacas y poco motivadoras para su personal.

La solución para estas situaciones pasa, en primer lugar, por realizar un análisis introspectivo de las condiciones de la organización. Mejorar la comunicación y el establecimiento de objetivos claros y comunes para un equipo de trabajo, por ejemplo, es una medida que puede mejorar bastante la implicación en un proyecto; o la recompensa -no necesariamente económica- por la consecución de objetivos puede incrementar la motivación y autoestima del grupo, y redundar positivamente en la producción.

Respecto al desarrollador, salvo en casos donde existen problemas estructurales graves como la falta total de vocación o capacidad, existen diversas vías para reconducir la situación.

TerapiaUna de ellas es mediante la comunicación entre las partes, algo así como organizar sesiones de terapia, reuniones donde la empresa pueda exponer al trabajador los hechos objetivos y los resultados de su comportamiento, y escuchar atentamente las motivaciones y argumentos de éste.

A veces, la producción negativa es un simple reflejo de actitudes desorganizadas, procrastinación, socialización excesiva, no finalización de tareas, estrés constante, falta de información, y otras muchas. Estas sesiones pueden servir para dar con las causas y acabar con la baja productividad de forma rápida.

Otra posibilidad para solucionar los problemas de productividad es la reasignación, el cambio hacia tareas más acordes con las habilidades y puntos fuertes de la persona. Por ejemplo, un NNPP dedicado habitualmente a la codificación podría convertirse en un buen verificador, o documentador, haciendo que sus aportaciones al proyecto pasaran a ser de signo positivo.

El último recurso es la destitución, que debería aplicarse únicamente una vez agotadas alternativas, digamos "menos violentas", como las citadas anteriormente. Lo normal es que un aviso lo suficientemente claro baste para despertar a cualquiera de su letargo, y no sea necesario llegar a mayores.

En cualquier caso, no cabe ninguna duda es del alto coste de los programadores con producción negativa neta. Un retraso en un proyecto o el lanzamiento de productos defectuosos puede tener un impacto terrible en la imagen de una empresa, y en el peor de los casos, hasta puede ocasionar desastres de magnitudes considerables. Y por no hablar de consecuencias internas, como la ruptura de la cohesión en equipos de trabajo, disminución global de productividad, aumento de desconfianza del grupo, incremento de costes, y un largo etcétera.

Semanas atrás Jay Field hablaba también de efectos nefastos para la propia industria del desarrollo de software, porque estos profesionales podían llegar a frenar el avance y la introducción de nuevas tecnologías, e incluso del terrible daño que se puede causar a las próximas generaciones de desarrolladores que durante su proceso de formación y adquisición de experiencia sean puestos a cargo de NNPPs.

Lamentablemente, los desarrolladores con producción neta negativa están aquí para quedarse. Tendrán hueco siempre que existan empresas donde no se cuiden detalles como el ambiente de trabajo, la transparencia, la comunicación, no se fomente la implicación y motivación del trabajador, o cuyos criterios de selección de personal consistan en elegir siempre a los profesionales de menor coste.

Enlaces:

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons