¿Por qué puede fallar una implantación de Team Foundation Server?

Muchas empresas están intentando implantar Team Foundation Server, lo que es una gran noticia, pues tengo puesta mucha fe en que esto mejore el nivel metodológico de las empresas que lo implantan.

Pero intuyo, que muchas empresas están fallando en este aspecto, no están logrando mejoras en el aspecto metodológico, solo están usando mejores herramientas, no mejores prácticas.

Por los comentarios que me llegan en cursos y charlas que imparto casí todas las empresas logran sacar beneficios en lo relativo a las mejoras a nivel de herramientas de Team Foundation Server (gestión de fuentes, gestión de bugs..), que no es poco, pero muchas empresas están desperdiciando la oportunidad que ofrece Team System en lo relativo a mejorar a nivel metodológico (entendio como las prácticas que usamos para desarrollar software, no como cómo de buenos somos siguiendo un plan trazado previamente).

Creo que esto tiene dos causas: la automedicación y la resistencia a aceptar los 'mindsets' y los principios de la metología elegida.

NUnitLe llamo automedicación al hecho de que la mayoria de las empresas están intentando implantar Team System por si mismas, sin la ayuda de alguien que conozca profundamente la herramienta y, aun más importante, las bases 'teoricas' que sustentan las características que Team System y Team Foundation Server proporcionan. Es dificil que alguien saque todo el provecho a las tecnicas que TFS proporciona si no entiende la esencia des estas técnicas y por qué aportan valor. Por mucho que tengas un excelente soporte para refactoring o para construcciones diarias, solo lograrás provecho de ellas si conoces sus fundamentos y las mejoras que se derivan para tu desarrollo si las utilizas. Instalando TS y TFS obtienes las herramientas, pero tus desarrolladaros no alcanzan por arte de magia un entendimiento y un convencimiento claro de por qué deben usarlas. Por ello, en mi opinión, para garantizar que vas a exprimir todo el valor que TS y TFS puede darte, primero necesitas formarte en las técnicas que TFS y TS te facilita poner en práctica. Luego necesitas formarte en las herramientas, pero esto quiza si que puedas hacerlo por ti mismo. Quien me lea pensará, vaya ¿en la herramientas si me puede formar yo mismo (ojo que no lo recomiendo) y en las técnicas no?. El razonamiento es facil: las técnicas estaban ahí antes de TS y TFS, sino las ponias en práctica es porque no las conocias y no concias su valor. Incluso las herramientas ya existian, no tan integradas y potentes como en TFS, pero plenamente usables: NUnit (testeo unitario), NAnt (construcción automática), miles de gestores de fuentes y gestores de bugs gratuitos etc… Si no usabas ya esas herramientas no vas a comprender su importancia y las mejoras que se derivan simplemente por instalar TFS y TS, por lo tanto probablemente hagas un uso precario de lo que TFS y TS ofrece.

Minsets y principios de MSF for CMMILa resistencia a aceptar los 'mindsets' y los principios de las metodologías es algo a lo que me enfrento habitualmente. Se suele hacer patente cuanto se intenta que TFS 'sirva para hacer partes de horas'. Olvidense, las metodologías que vienen con TFS no miden nada en función de las horas trabajadas, sino en función de las características que incluye un build y su calidad. Si no eres capaz de entender esto, mejor olvidate de las metodologías de TS y sigue usando la metodología ASM (A Salto de Mata by Miguel Egea). Muchas empresas cuando usan TFS y TS, elijen una metodología porque no queda más remedio, pero no asumen los 'mindset' y los principios, no cambian sus ideas acerca del desarrollo de software. Pocas mejoras surgen de seguir haciendo lo mismo con diferentes herramientas. Las mejoras metodológicas solo surgen del convencimiento de la necesidad de hacer las cosas de otra manera, basandonos en diferentes principios. Y eso no se logra simplemente con iniciar un proyecto en Team System, es necesario un proceso paralelo de 'mentoring', por el cual, alguien que realmente conozca esos principios y lleve tiempo poniendolos en práctica, los transmita a nuestro equipo de desarrollo. Una cosa es elegir una plantilla metodológica y otra asumir que todas nuestras acciones deben ir encaminadas a trabajar siguiendo una visión común, a crear un equipo con el cliente, a logra un equipo de iguales, a ser agiles y estar preparados para el cambio (incluso en MSF CMMI!!! para sorpresa de muchos), por poner algunos ejemplos…

Mi recomendación (no digo que no sea arrimar el ascua a mi sardina): si te planteas usar TFS, contrata a alguien que sepa de Gestión de Proyectos, que lleve tiempo usando técnicas como construcciones frecuentes, testeo unitario, gestión de bugs etc… y haciendo las cosas de acuerdo a los principios que son la base de las metodologías que se incluyen con TFS. Y aun más importante, asume que tendrás que cambiar la manera en la que haces las cosas, las cosas no cambian haciendo lo mismo.

Diseño físico de bases de datos en SQL Server 2005

He estado leyendo un interesante 'whitepaper' sobre como diseñar el despliegue físico de las bases de datos en SQL Server 2005. A parte de unos buenos indices, un buen despliegue físico es vital para asegurar el correcto rendimiento y la escalabilidad de nuestra instalación de SQL Server y por lo tanto de nuestra aplicación/es.

En este 'whitepaper' se cubren aspectos relativos al diseño de los archivos de almacenamiento de nuestra base de datos, consideraciones sobre el hardware del servidor de datos (discos, interfaces, buses, niveles RAID etc…) y revisas diferentes patrones de carga a los que puede estar sometido nuestro servidor y los requisitos de I/O de diferentes tamaños de aplicación.

El documento recomienda una serie de pasos a dar a la hora de abordar el diseño físico de la base de datos y nos enseña como darlos:

1. Caraterizar la carga de Entrada/Salida de la aplicación
2. Determinar los requisitos de confiabilidad y rendimiento del sistema de base de datos
3. Determinar los requisitos de hardware necesarios para soportar las deciones hechas en los pasos 1 y 2
4. Configurar SQL Sever 2005 para aprovechar los cambios hecho en el paso 3
5. Hacer seguimiento del redimiento en respuesta a los cambio en la carga 

Tambien da una serie de recomendaciones, que traduzco aquí, si quereís saber la justificación teneís que leer el documento:

• Siempre utilizar 'Page Checksum' para auditar la integridad de los datos.
• Considerar la utilización de compresión para grupos de archivos de solo de solo lectura para una mayor eficiencia en el almacenamiento.
• Utilizar NTFS por seguridad y para disponer de algunas caracteristicas avanzadas de SQL Server 2005.
• Usar 'instant file initialization' para optimizar el rendimiento.
• Utilizar Windows Network Service Account por seguridad.
• Utilizar crecimento manual de archivos de la base de datos.
• Usar particionado de datos (solo disponible en Enterprise Edition) para una mayor flexibilidad
• Alinear el almacenamiento de índices con sus tablas para un mantenimiento más facil y rápido.
• Alinear el alamacenamiento de las tablas comumente utilizadas juntas en 'joins' para obtener mejor rendimiento y mejorar el mantenimiento.
• Elejir el nivel de RAID con cuidado. Para un rendimiento excelente y alta confiabilidad tanto en patrones tanto de lectura como en escritura elija RAID10, para patrones de solo lectura elija RAID5.
• Para lograr paralelismo en Entrada/Salida optimizado utilize un tamaño de banda de 64Kb o 256Kb.
• Para mejorar la escalabilidad a futuro y facilitar el mantenimiento, utilize puntos de montaje de volumenes.
• Para incrementar la confiabilidad en el ancho de banda de bus, utilice software de 'multipathing'.
• Para pequeños servidores con menos de tres dicos PCI puede ser suficiente, sin embargo PCI-X está recomendado y puede servir un mayor rango de cargas de trabajo.
• Utilizar discos enchufados directamente es el enfoque recomendado para servidores pequeños a medianos.
• Se recomienda utilzar SAN para grandes servidores.
• Los sistemás NAS no se recomiendan, mejor usar iSCSI en su lugar.
• Para mejorar la capacidad de recuperación, utilize SCSI en lugar de SATA o IDE.
• Para grandes cargas, utilize SCSI o SATA con soporte TCQ.
• Almacenar el log de trasacciones separado de los archivos de datos. No en una banda en el mismo disco que los archivos de datos.
• Para grandes demandas de ancho de banda en el bus de Entrada/Salida, utilizar un bus diferente para los archivos del log de transacciones.
• El número de archivos de datos en un único grupo de archivos debe ser igual al número de CPUs.

Lista de comprobación de supervivencia de proyectos

He traducido al castellano el Test de supervivencia de proyectos de Steve McConnell que es uno de los autores clave en la gestión clasica de proyectos. Esta lista tiene su origen en el libro Software Project Survival Guide.

Esta lista es interesante porque muestra todos los elementos de los que se debe preocupar un Jefe de Proyectos que siga una metodología clasica.

Web Service Software Factory

Recientemente se ha liberado la factoría para desarrollo de servicios web: Web Service Software Factory. El proposito de esta factoría, completamente integrada con Visual Studio 2005, es servirnos de guia y facilitarnos el empleo de las mejores prácticas a la hora de diseñar y desarollar la capa de servcios de nuestras aplicaciones.

En esta factoría encontraremos:

Documentación: Sobre arquitectura de aplicaciones se servicios web, diseño de los mensajes que intercambiarán los servicios, manejo de excepciones y sobre migración y planeamiento hacia WCF.

Asistentes: Orientados a generar desde los datos las entidades de acceso y la capa para exponerlas mediante servicios web.

Una implementación de referencia: Que muestra como implementar, utilizando los anteriores elementos, una solución, mostrando además como integrar otros elementos vitales en una aplicación empresarial, como el logeo y la gestión de excepciones

Si esto os parece interesante no dudeís en hecharle un vistazo al HOL sobre esta Web Service Software Factory, para comenzar a meteros en harina.

Taylor se equivoco… en lo que se refiere a la informática.

Frederick W. Taylor fue uno de los primeros 'economistas' en proponer mediante estudios serios la especialización de los operarios industriales, es de lo poco que recuerdo de la asignatura de Economía de la Empresa. La idea era simple: Si el trabajador realiza siempre las mismas tareas cada vez las hará con más destreza y en menor tiempo. Evidentemente en el siglo XIX no podía pensar en que muchos trabajadores se dedicarían a 'desarrollar software'. Y desde luego la idea de la especialización es cada vez menos aplicable al desarrollo de software, y en general a toda actividad en la que el conocimiento sea el aspecto central de la naturaleza del trabajo a desarrollar.

Cada vez los desarrollos de software utilizan más tecnologías. Hace solo unos años, cuando yo comenzaba en esto, los desarrollos de software se reducían a un ejecutable y unas cuantas librerías dinámicas en el mejor de los casos. Los sistemas eran cliente servidor, el enfoque del especialista funcionaba. Pero ahora los proyectos son cada vez más complejos. Un proyecto medio incluye, fácilmente, un gestor de bases de datos, un servidor web, una tecnología de acceso a datos, integración con un servidor de correo, integración con un servidor de directorio, integración con un gestor de contenido, etc…

Sin duda para ser un buen desarrollador en los tiempos que corren hay que ser un generalista, ya no es posible desarrollar software siendo un maestro del C++. Es necesario conocer muchos más ámbitos que solo la escritura de código en un lenguaje o en varios. Poder tocar varias tecnologías con naturalidad es un requisito en los proyectos actuales. Esto no quita que la especialización sea necesaria, hay que tener en cuenta que sin cierto grado de especialización es necesario para resolver ciertos problemas complejos.

Desde un punto de vista de organización de los proyectos de desarrollo, los generalistas son muy valiosos, pues son los que son capaces de conocer como todos los elementos de la aplicación casan juntos y suelen ser más propensos a valorar el conocimiento de los demás miembros del equipo y aprovecharlo para aprender, a colaborar con ellos y valorar su trabajo.

¿Pero entonces como cubrimos la necesidad de especialización? El enfoque es claro, no solo queremos generalistas, queremos los que Scott Ambler llama 'especialistas generalizadores'. Un especialista es un maestro en algún asunto concreto. Un generalista conoce muchos temas y como trabajan juntos, pero ninguno con extraordinaria profundidad. Un 'especialista generalizador' conoce muchos aspectos y además es un maestro en algunos de ellos. Habrá quien diga que no existen estos, que es muy difícil encontrarlos, pero a mí me vienen unos cuantos nombres a la cabeza: Unai Zorrilla, por ejemplo lo sabe todo de dispositivos móviles, y un motón de WWF, WCF etc… o Iván González, que lo mismo le da a los sistemas (¿su campo natural?) que al desarrollo y que sabe absolutamente todo sobre IIS… o por poner alguien de fuera, José Alarcón, que no solo es un crack del ASP.Net, sino que además es capaz de gestionar una empresa creada por el mismo… Hay muchos más a los que admiro como desarrolladores (en el sentido amplio de la palabra).. David Carmona, José Murillo, Pablo Pelaez, Jorge Serrano, Marco Amoedo, Cristian, Eladio Rincón,… (conste que la lista no esta completa!!!) si pienso que tipo de profesionales son, claramente llego a la conclusión de que son 'especialistas generalizadores'.

Invocar al Servidor Web de Visual Studio 2005 desde el Explorador

Como muchos ya sabeís Visual Studio 2005 trae un servidor Web propio que nos permite servir y depurar nuestras aplicaciones web sin necesidad de tener un servidor IIS instalado en la máquina.

Pues bien, desde hace un tiempo estoy utilizando un truqillo que leí en alguna parte realmente util. Consiste en poder abrir desde el menu contextual del Explorador sobre una carpeta un servidor web que exponga esa carpeta en el puerto 8080 (aunque se puede cambiar lógicamente) de nuestra maquina. Luego bastará navegar a http://localhost:8080.

Para tener disponible este menu, simplemente tenemos que modificar el registro de Windows. La manera más facil es crear un archivo .reg con el siguiente contenido:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREClassesFoldershellVS2005 WebServer]
@="Iniciar Servidor Web ASP.Net 2.0 aquí"

[HKEY_LOCAL_MACHINESOFTWAREClassesFoldershellVS2005 WebServercommand]
@="C:\Windows\Microsoft.NET\Framework\v2.0.50727\Webdev.WebServer.exe /port:8080 /path:"%1""

Los mas perezosos podeís Menu Explorador Servidor Web ASP.Net.reg directamente y ejecutarlo.

El resultado es el que se aprecia en esta pantalla:

Dependencias circulares de formularios en C++/CLI

Es una situación relativamente habitual que dos clases se tengan que conocer entre sí, es lo que se conoce como referencia circular. Aunque en principio debería sospechar de esta situación por el alto acoplamiento que introduce entre ambas clases, hay veces, en que puede ser excesivo crear una clase para que maneje la comunicación entre las clases. De todos modos si decidís usar este enfoque, una buena implementación es utilizar el patrón mediator Mediator.

Cuando esto nos ocurre en lenguajes como C# no hay problema, porque no existe el concepto de declaración e implementación de una clase separadas. Pero en C++ toda clase debe conocer la declaración de otra clase que quiera utilizar y el compilador debe ser capaz de encontrar la implementación. El problema es que si A conoce ve y B conoce A cuando el compilador llega a la compilación de la primera de ellas que encuentra en nuestro código no puede saber que es la segunda. Recordemos que la compilación en C++ se hace modulo a modulo y que es el linkado el que pone todo junto. Los errores suelen ser del estilo:

Error 2 error C2065: 'FChild' : undeclared identifier FParent.h 76 
Error 3 error C2065: 'child' : undeclared identifier FParent.h 76 
Error 4 error C2061: syntax error : identifier 'FChild' FParent.h 76 
Error 5 error C2227: left of '->MdiParent' must point to class/struct/union/generic type FParent.h 77 
Error 6 error C2227: left of '->Show' must point to class/struct/union/generic type FParent.h 78
 

El mecanismo habitual para resolver esta situación es utilizar "forward declaration" o declaración adelantada. Hasta aquí sin problema.

#pragma once

#include "B.h"

 

ref class B; //forward declaration

 

ref class A

{

public:

  B^ b;

};

Más sobre "forward declaration" en las siguientes entradas de C++ FAQ Lite:

  • [39.11] How can I create two classes that both know about each other?
  • [39.12] What special considerations are needed when forward declarations are used with member objects?
  • [39.13] What special considerations are needed when forward declarations are used with inline functions? 
  • El problema surge cuando utilizamos C++/CLI y Visual Studio, y queremos comunicar dos formularios, situación habitual fruto de la necesidad de que un formulario se comunique con su padre en interfaces MDI (la propiedad MDIParent devuelve una referencia al padre y el padre suele ser quien crea el formulario hijo) o que el formulario lanzado obtenga datos de su lanzador y viceversa. Son claros casos de referencia circular.

    Bueno pues siguiendo con lo expuesto anteriormente intentamos resolver la referencia circular utilizando "forward declaration" y… NO FUNCIONA!!!!. Obtenemos errores del tipo:

    El problema es que el diseñador de formularios de Visual C++ 2005 solo es capaz de trabajar con clases de formulario definidas en el archivo .h (definiciones inline), si separamos la clase en .h y .cpp, el diseñador deja de funcionar. Luego tenemos que conseguir que funcione la predeclaración usando funciones inline.

    Tal y como se puede leer en la faq [39.13] el orden de las declaraciones es critico cuando usamos "forward declaration" con funciones inline. Esto es fácil si ambas clases se definen e implementan en el mismo archivo .h, pero esto no suele ser viable. Pues bien el truco es cambiar la posición donde se realizan los includes, para que las clases de definan en el orden adecuado:

    /* Archivo A.h */

    #pragma once

     

    ref class B;

     

    ref class A

    {

    public:

      A(void)  {}

     

      void GetB();

    };

     

    #include "B.h"

     

    inline void A::GetB()

    {

      B^ b = gcnew B();

    }

     

    /* Archivo B.h */

    #pragma once

     

    ref class A;

     

    ref class B

    {

    public:

      B(void){}

     

      A^ GetA();

    };

     

    #include "A.h"

     

    inline A^ B::GetA()

    {

        return gcnew A();

    }

    Podéis descargar un ejemplo referencias circulares C++/CLI, basado en WinForms.

    Team Build Sidekick addin

    Team Build Sidekick es una addin para el Team Explorer de Visual Studio que extiende la funcionalidad disponible en Team Explorer a la hora de definir tipos de Builds. Además está disponible el código fuente y un artículo muy interesante que describe el modelo de objetos de el servidor de versiones de Team Foundation.

    Resumiendo la funcionalidad que proporciona este addin es la capacidad de hacer checkout, modificar y hacer checkin de archivos .proj de un tipo de build directamente desde el árbol del proyecto.

    Arquitectura en tres capas con ASP.Net

    Existe en MSDN un interesante tutorial sobre como crear aplicaciones Asp.Net en tres capas. Sin duda el enfoque presentado en el artículo es adecuado para aplicaciones pequeñas y medianas, pero voy a comentar algunas mejoras que yo haría y por qué. Estas mejoras que propongo son practicamente obligatorias si se trata de la arquitectura de una aplicación empresarial.

    Sería interesante exponer la capa de negocio a través de una fachada de servicios web, o lo que es lo mismo ir a una arquitectura en cuatro capas. La motivación es desvincular completamente la capa de interfaz de usuario de la capa de negocios, y no cerrarnos la puerta a la posibilidad de tener una interfaz que no este basada en Asp.net o poder elegir un enfoque "Smart Client".

    Otra mejora necesaría seria, a mi modo de ver, separar totalmente los objetos contenedores de datos (DataSet) de la lógica de actualización de los mismos (TableAdapter). Esto permite desacoplar estos dos conceptos completamente. La capa de servicios web, necesita conocer los objetos contenedores de datos y los objetos de negocio, pero para nada los objetos de acceso a datos. Si no separamos estos dos conceptos, la fachada de web services tendrá acceso directo a los TableAdapter. Para esto sería necesario abandonar los TableAdapter y utilizar DataAdapter en su lugar, pues estos no no están directamente vinculados con los DataSet. Una gran mejora a futuro sería que el asistente que genera los DataSet y sus DataTable asociados permitiese elegir que se generasen en ensamblados separados, ahora, hasta donde yo se, esto no se puede hacer.

    Un error habitual cuando, que el tutorial no comente, pero que voy a comentar aqúi, es hacer toda nuestra capa de acceso a datos y de negocios con clases estáticas, esto no es malo en principio, pero el problema cuando se elije este enfoque es que tendemos a almacenar la conexión como un miembro estático de nuestras clases y esto va contra la práctica que abrir tarde la conexión, cerrarla pronto y no compartirla entre operaciones.

     

    Recien salido del horno: Visual Studio 2005 SDK version 3.0 RTM

    Ya tenemos a nuestra disposición la nueva versión del SDK de Visual Studio 2005, cabe destacar entre las novedades de este SDK:

      • Annotate: Que permite ver quien modifico por útima vez una linea de código. Herramienta que ya existia, pero que ahora se integra con Visual Studio y muestra sus resultados visualmente.

      • TreeDiff: Que permite comparar dos ramas de código fuente visualmente, resalta las diferencia y permite resolverlas.

    • Información y ejemplos de IronPython
    • Herramientas de generación de sintaxis y parsers (MPPG / MPLEX), unas curiosas herramientas primas hermanas de los conocidos lexx y yacc que permiten a partir de una gramática expresada estilo lexx/yacc, nos genera esta gramatica y un parser para la misma en C#.

    • NO incluye VSTA, aun en versión preliminar, si quereís usar VSTA hay que descargar la versión anterior del SDK (August 2006 CTP)