¿Es lo mismo arquitectura por capas y N-Tier?

Me parece importante, para optimizar la comunicación entre profesionales, que todos tengamos claros los conceptos y los apliquemos para referirnos exactamente a lo mismo. Esto nos evita malas interpretaciones y errores muy críticos sobre todo en entonos de desarrollo rápido de aplicaciones (RAD). 

Existen dos conceptos arquitectónicos que a veces tendemos a confundir. Estos son la “Layered arquitecture” (arquitectura por capas) y la “N-tier arquitecture” (arquitectura de N-niveles). Me voy a referir a ellas sin traducirlas, puesto que ambos conceptos (“layer” y “tier”) pueden verse traducidas (erróneamente en el caso de “tier”) como “capa” lo cual fomenta aún más la propensión a errores.

Veamos primero que es exactamente “Layered architecture”: 

Se centra en una distribución jerárquica de las roles y responsabilidades proporcionando una separación efectiva de las preocupaciones. (cada cual que se apañe con sus problema…). El rol indica el modo y el tipo de interacción con las otras capas, y la responsabilidad indica la funcionalidad a alcanzar.

Por ejemplo, el diseño de una típica aplicación Web comprende una capa de presentación (funcionalidad relacionada con la U.I.), capa de negocio (procesamiento de reglas de negocio) y capa de datos (funcionalidad relacionada con el accesos a datos.)

El estilo de arquitectura por capas tiene algunas características que  la identifica:

  • Describe una descomposición de servicios de tal manera que las interacciones ocurren normalmente entre capas vecinas. (depende de lo laxos que queramos ser…)
  • Las capas de la aplicación pueden residir en el mismo ordenador fisco o pueden estar distribuidas en separados equipos. El concepto de distribución se aplica siempre que se produzca el mecanismo de marshaling para realizar una comunicación (siempre que no se comparta espacio de memoria…)
  • Los componente de cada capa se comunican con otros componente de otras capas a través de un conjunto de interfaces bien definidos. (sino apañados vamos…)
  • En alguna ocasión ha sido descrito como “pirámide invertida de reutilización” donde cada capa agrega sus propias responsabilidades  y abstracciones a la capas que están por debajo.

Que beneficios conseguimos aplicando esta distribución en capas?

Abstracción, encapsulamiento, capas de funcionalidad muy bien definidas, alta cohesión, reusabilidad (las capas inferiores de la pirámide no tienen dependencias de las superiores por lo que es fácil reutilizarlas) y débil acoplamiento (comunicación basada en abstracciones)

La separación, reduce el riesgo y el impacto de los cambios tecnológicos. Por ejemplo al cambiar el mecanismo de persistencia de la aplicación las capas que lo consumen no tienen porque realizar cambios. Además aumenta el rendimiento (a partir de cierta carga de trabajo) al distribuir las capas sobre múltiples capas físicas. También aumenta la escalabilidad y la tolerancia a fallos.

Este escenario es propicio para implementar una buena política de pruebas, permitiendo conmutar entre diferentes implementaciones de los interfaces (mock, servicios reales…)

Por otro lado tenemos la N-Tier architecture

El estilo de despliegue de esta arquitectura describe la separación de la funcionalidad en diferentes segmentos, de manera similar a la arquitectura por capas. pero cada segmento es un nivel que se encuentra físicamente en un equipo independiente.

Es un estilo que define el despliegue de las capas de la aplicación, se caracteriza por por una descomposición funcional de la aplicación, componentes de servicios y su despliegue distribuido, proveyendo mejoras de escalabilidad, disponibilidad  y utilización de recursos.

Cada capa es completamente independiente del resto, excepto de aquella/s se encuentran inmediatamente por debajo de ella. La capa n sabe como manejar las peticiones a la capa n+1, como trasladar dicha petición a la capa n-1 (si es que existe) y como tratar el resultado de la misma.

Las arquitecturas con “N-Tiers” poseen por lo menos 3 capas lógicas separadas. Cada capa tiene una funcionalidad especifica, de la cual es responsable y están localizadas en diferentes servidores físicos. Una capa (“layer”) se despliega en un nivel (“tier”) si más de un servicio o aplicación es dependiente de la funcionalidad expuestas por la capa.

Veamos los beneficios que nos aporta esta arquitectura:

  • Mantenibilidad
    Cada nivel es independiente de los demás, con lo que se consigue independencia. Se puede actualizar o modificar un nivel sin afectar a la aplicación en su conjunto. 
  • Escalabilidad
    Es razonablemente sencillo escalar puesto que los niveles están basadas en el despliegue de las capas.
  • Flexibilidad
    Cada nivel puede ser gestionado o escalado independientemente, lo cual aumenta la flexibilidad.
  • Disponibilidad
    Las aplicaciones pueden explotar la arquitectura modular empleando componentes fácilmente escalables.

Resumiendo un poco :

Podemos decir que para que una aplicación sea “N-Tier”, es condición necesaria pero no suficiente que mantenga una arquitectura por capas. Esta característica nos permite cumplir los requisitos de despliegue (3 o más capas separadas) que hacen a una aplicación “N-Tier”.

Dulce introducción al Kanban!!

Bueno, parece que SCRUM ha puesto la pica en Flandes y se ha convertido en una metodología ampliamente conocida y respetada. Pues ya está, no? ya tenemos metodología ágil para cualquier tipo de proyecto y para siempre…

Muy confiado tienes que ser para creerte eso…

En mi trabajo hemos desarrollado un producto aplicando SCRUM con unos resultados muy satisfactorios. Dicho producto, se ha comenzado a implantar y ahora entra un equipo de soporte a mantener la primera versión del mismo y comienza una nueva rama de desarrollo de la siguiente versión.

Estaba planteándome como organizar el equipo de soporte y no acababa de encajar SCRUM sobre la naturaleza de su trabajo (la verdad que esta y cualquier otra metodología…). Es muy difícil organizarse para planificar incluso un pequeño Sprint, puesto que no se conocen las tareas de antemano. Por lo tanto, llegué a la conclusión de que necesitamos para este tipo de proyectos (que no son pocos) algo todavía más adaptable que SCRUM…

Tomando un café con el gran (aunque javero) Jorge Prieto me comentó algo sobre Kanban y comencé a tirar del hilo para ver si me podía cuadrar eso que sonaba a pescado crudo…

Así que vamos a aprovechar este post para explicar que es eso de Kanban compararlo con SCRUM e identificar sus conflictos potenciales. Antes que meternos en harina vamos a dejar las cosas claras, haciendo un pequeño resumen de SCRUM y Kanban

SCRUM (en pocas palabras)

  • Divide su organización en pequeños equipos auto-organizados y multidisciplinares.
  • Divide el trabajo en una lista de pequeños elementos muy concretos.
  • Ordenar la lista por orden de prioridad y estimar el esfuerzo relativo de cada elemento.
  • Dividido en iteraciones cortas de longitud fija (normalmente con entrega o demostración después de cada iteración.)
  • Optimizar el plan de liberación y actualizar las prioridades en colaboración con el cliente, sobre la base de conocimientos adquiridos por la inspección de la entrega después de cada iteración.
  • Optimizar el proceso por tener una retrospectiva después de cada iteración.

Resumiendo el resumen:

Pasamos de “Muchas personas haciendo algo muy grande” a “Pocas personas haciendo cosas pequeñas que se integran con regularidad para ver el conjunto.”

Kanbas (en pocas palabras también)

  • Visualizar el flujo de trabajo
    Dividir el trabajo en trozos escribir cada uno de los elementos en una tarjeta y poner en la pared.
    Usar el nombre o columnas para ilustrar en que estado se encuentra cada elemento dentro del flujo de trabajo.
  • Límitar WIP (Work In Progress)
    Asignar límites explícitos obre cuantos elementos pueden estar en cada uno de los estados del flujo de trabajo.
  • Medir el tiempo
    Contar el tiempo promedio para completar un tema, a veces llamado «tiempo de ciclo» y, como es obvio, optimizar el proceso para que el tiempo tan pequeño y previsible como sea posible.

image

 

Podemos observar que Kanban es todavía menos prescriptivo que SCRUM.

Prescriptivo significa “reglas para seguir”. 100% prescriptivo implica que no tienes que usar el cerebro, ridículo verdad?…) y en este apartado vemos que SCRUM aporta mas reglas “out-of-the-box” como por ejemplo encajar en un tiempo los Sprints cosa que Kanban no hace.

Para hacernos una mejor composición podemos observar la escala de “prescriptividad” (toma ya!) de forma gráfica:

image

Como siempre podemos decir que la mejor opción es no limitarse a un herramienta en concreto. Probablemente la solución nuestros problemas se encuentre en una combinación de varias. Muchos equipo Kanban realizan una reunión diaria a primera hora (típica liturgia de SCRUM). Algunos equipos de SCRUM que he conocido, escriben su Backlog como Casos de Uso (típico de RUP) o limitan el tamaño de las colas (típico de Kanbas).

Así que como siempre “haz las cosas como mejor te funcionen”, ya os contaré el resultado de aplicar esta forma de trabajo con el equipo de soporte.

Para terminar os cito a Miyamoto Musashi que los japoneses algo saben de todo esto:

“No desarrolles ninguna dependencia de arma o escuela de lucha”

Los mejores países para hacer negocio

Si estáis pensando en globalizar vuestras líneas de negocio o cambiar de aires profesionales, os puede resultar interesante saber que el World Bank Group ha publicado su informe anual «Doing Business» que clasifica 181 países sobre lo propicio que es su regulación hacia los empresarios.

El informe proporciona una medida cuantitativa de la normativa, que sirva como soporte a la decisión de abrir un negocio y se aplica a las pequeñas y medianas empresas nacionales. Las economías están clasificadas en base a un índice de facilidad de hacer negocios. (Índice creado por el propio World Bank Group)

Los valores más altos de este índice indican un conjunto de reglamentos más ventajosos para las empresas y el fortalecimiento de la protección de los derechos de propiedad.

Facilidad de hacer negocios:

  1. Singapur.
  2. Nueva Zelanda.
  3. Estados Unidos.
  4. Hong Kong. (es una Región Administrativa Especial…)
  5. Dinamarca.
  6. Reino Unido.
  7. Irlanda.
  8. Canadá.
  9. Australia.
  10. Noruega.

Los criterios tenidos en cuenta a la hora de confeccionar este ranking son:

  • Facilidad de hacer negocios
    Procedimientos, tiempo, costo y capital social mínimo para abrir un nuevo negocio.
  • Permisos de Construcción
    Procedimientos, tiempo y costo para obtener permisos de construcción, las inspecciones y las conexiones de servicios públicos.
  • Emplear trabajadores
    Índice de dificultad de contratación, índice de rigidez de horas, índice de dificultad de despido, coste de despido.
  • Registro de la Propiedad
    Procedimientos, tiempo y costo para la transferencia de bienes inmuebles comerciales.
  • Obtención de crédito
    Fuerza de los derechos legales, profundidad de crédito.
  • La protección de los inversores
    Fuerza de la protección de los inversores, grado de divulgación, grado de responsabilidad del director y la facilidad de adaptación del accionista.
  • Impuestos
    Número de pagos de impuestos, el tiempo necesario para preparar y presentar declaraciones de impuestos y pagar los impuestos, relación del total de impuestos con el porcentaje del beneficio.
  • Comercio a través de las fronteras
    Documentos, tiempo y el costo para exportar e importar.
  • El cumplimiento de los contratos
    Procedimientos, tiempo y costo para resolver una disputa comercial.
  • Cierre de una empresa
    La tasa de recuperación de la quiebra.

Como podéis comprobar está todo pensado…

Si queréis profundizar más en el tema, pasaros por aquí World Bank – Doing Business

¿Por que iterar?

Aplicando el patrón C.S.P. (Common Sense Pattern…) en nuestros desarrollos, observamos que debemos cumplir con las necesidades del cliente. Acto seguido, descubrimos, que estas cambian más que los nos gustaría (ouchh!). Por lo tanto, se crea la necesidad de ir ajustando el avance del proyecto a las necesidades reales (y cambiantes) del proyecto.

¿Pero como…?

La respuesta que nos aportan las metodologías agiles es sencilla, iterando. Partiendo el desarrollo de la aplicación en pequeños entregables que el usuario pueda probar e ir enriqueciendo. Suena lógico, pero vamos a hacer un esfuerzo de plasmar negro sobre blanco las principales ventajas que esta forma de trabajar nos ofrece:

  • Gestión de riesgos
    Asumámoslo, el resultado deseado no es concebible por adelantado. Existen riesgos, algunos ya identificados y otros por identificar. Para gestionarlos correctamente debes demostrar o refutar tus requisitos y diseñar las suposiciones implementando incrementalmente elementos que son objetivos del sistema, empezando con los de más alto riesgo.
  • Económicos
    En un ambiente de negocio incierto (casi todos los proyectos lo son !!) es clave optimizar los esfuerzos en las mayores prioridades del proyecto. Debemos manejar cada iteración como un conjunto de fichas de juego a apostar por un conjunto de funcionalidad que se pueda entregar, probar y que funcionen.
  • Enfoque
    Solo podemos mantener una cantidad limitada de elementos en la mente. Trabajando con pequeños lotes de trabajo podemos focalizar nuestros esfuerzos con un conjunto de funcionalidades que comprendemos y somos capaces de encajar y entender.
  • Motivación
    No existe un mecanismo mejor de motivación de acción prolongada (el dinero solo motiva en un espacio reducido de tiempo!!) para un profesional que comprobar como su creación se usa, es efectivo y valorado por los usuarios.
  • Control de la teoría
    Las iteraciones nos permiten controlar mejor las desviaciones, reduciendo el impacto de los errores en las estimaciones y crear un mecanismo de retroalimentación sobre los planes del proyecto.
  • Implicación de los interesados
    Los patrocinadores (clientes, usuarios, dirección…) pueden observar los resultados más rápidamente (cumpliendo así con la visibilidad, requisito fundamental de cualquier desarrollo) y así aportar mayor compromiso, implicación y financiación.
  • Aprendizaje continuo
    Todos los actores del proyecto aprenden en cada iteración. Los miembros del equipo adquieren conocimiento funcional y aportan mejoras desde la prospectiva tecnológica y los funcionales comprenden las implicaciones de automatizar los procesos empresariales. Todos aportan y el proyecto crece rápido y mejora.

Ya tenemos un conjunto de argumentos para convencer a los stakeholders más peleones acerca de las bondades de trabajar en pequeñas iteraciones, ahora el que quiera entender que entienda…

Reflexión "reposada" sobre las metodologías ágiles

A lo largo de los años de experiencia que tengo en el sector de la informática he visto pasar muchas tendencias de largo. Algunas eran buenas ideas mal planteadas, (otras malas directamente) que simplemente no consiguen hacerse un hueco en la comunidad de stakeholders implicados.

En ocasiones han fracasado porque cargaban la balanza de un único lado dejando fuera a la otra parte del negocio. Nos guste o no, estamos obligados a entendernos puesto que en esto que este negocio de la informática tan importante es vender como desarrollar. Como una de las dos partes de la ecuación se sienta fuera del juego nunca una metodología podrá cuajar a alto nivel.

Hace ya un tiempo que estamos oyendo hablar de las metodologías ágiles y con la perspectiva que nos da el tiempo, podemos decir que estas tienen algún que otro as en la manga que las pueden hacer triunfar donde otras fracasaron. (Es verdad que la cosa es más fácil cuando el vecino ya se ha pelado la barba…)

Podemos decir que las cosas están cambiando y más rápido de lo esperado.

Poco a poco, el sector del desarrollo del software se va haciendo un hombrecito. Desde luego este proceso no se ha pospuesto por falta de esfuerzos. La industria, cual madre concienciada, haciendo palanca a través de la Ingeniería del Software ha intentado estandarizar de muchas maneras el “artístico” proceso de crear software. Algunos de estos intentos han sido más forzados que otras (UML, CMMI, Métricas de calidad… ), pero casi todos, por diversos motivos, han demostrado la misma poca efectividad. (Por cierto el VS2010 incluye soporte para los 6 documentos principales de UML!!)

Dichos intentos “encauzadores” de mamá industria han quedado a medio camino por la misma razón, partían de un axioma equivocado:

Todas las metodologías predictivas asumen el resultado del proceso de análisis y diseño como verdades inmutables que constituyen los cimientos sobre los que edificar el resto del proyecto.

Centrando sus esfuerzos en conseguir un terreno firme en el que apoyarse, la realidad, obstinada, nos demuestra que realmente lo hacían sobre arenas movedizas. No por que el resultado de tales esfuerzos estuviera mal hecho  (existen toneladas de documentación sobre como optimizar el proceso de toma de requisitos…) sino por simplificar en exceso el contexto (desestimando el factor cambiante) de cualquier proyecto de Software.

¿Cuantas veces nos ha ocurrido al terminar un proyecto que si lo volviésemos a empezar lo atacaríamos de otra forma…? En relación a otras ciencias (y entornos productivo-económicos) el desarrollo de software avanza muy rápido obligándonos a descartar metodologías de éxito en otros ámbitos por la naturaleza de nuestro negocio.

Alcanzar esta velocidad de crucero implica que hay mucho que mejorar y obliga al sector a reinventarse continuamente. La tecnología, los modelos de negocio, el alcance de la funcionalidad de las aplicaciones, la automatización de procesos, la integración y orquestación de unidades de negocio… todo está en ebullición. Como todos sabemos, no se puede estandarizar lo que no deja de cambiar, por lo que los intentos realizados se han ido quedando anticuados antes de alcanzar su madurez.

Pero en ese reinventarse ha cambiado la perspectiva…

Un buen día nos damos cuenta de que estamos peleando contra la realidad. Nos liberamos y dejemos de atacar y evitar el cambio como un enemigo. Es una actitud provocada por el convencimiento que surge desde dentro de que no hay otra opción. Debemos asumir (cuanto antes mejor) el cambio como algo que está ahí, nos guste o no, no podemos evitarlo. ¡¡Todo cambia!!

En las metodologías predictivas se destinan gran parte de los recursos a ser capaz de predecir lo que se va a desarrollar en los próximos años. Por muy concienzudo que sea dicho estudio, el contexto varía, las necesidades del cliente cambian, surgen nuevas oportunidades y riesgos. El que mayor capacidad de cambio demuestre, contará con una ventaja competitiva significativa.

Por lo tanto, permitir que nuestro cliente marque el siguiente paso a dar (o mejor dicho, pasito…) nos permite alinear el camino a recorrer con las necesidades del cliente que sobre la marcha surjan, aportando un mayor valor al software y satisfacción al cliente, que es (o debería ser) nuestro objetivo.

Aplicaciones multilenguaje ASP.NET MVC

El desarrollo de capa de presentación Web en .NET ha cambiado desde que Microsoft se decidió a realizar una implementación oficial del conocido patrón MVC en la plataforma ASP.NET y la (amplia) comunidad de desarrolladores de ASP.NET lo asumió con todos los cambios que implica.

Y esta implementación ha calado rápido y profundo, (ya se está desarrollando la segunda versión) ha llegado a la gente acostumbrada a Frameworks ligeros de desarrollo web que incluían sus propias implementaciones de MVC. Entre otras ventajas, ha ayudado a estandarizar la organización de los archivos del sitio y refinar las responsabilidades (Controladores -> Procesos de interfaz de usuario, workflow de la aplicación… Vistas –> mostrar la información de manera amigable y recoger los datos, validaciones de formato…).

Si deseamos acogernos a la implementación de Microsoft de dicho patrón deberemos ir encajando los problemas la funcionalidad de toda la vida sobre estas nuevas reglas de juego.

Uno de los requisitos clásicos más general es que nuestra aplicación disponga de características de globalización / localización. La idea general es la de siempre, evitar incluir ninguna referencia explicita a una determinada cultura y jugar con las características de globalización que nos ofrece el .NET Framework. Pero como ya sabemos, en Web todo se complica un poquito más. Al correr sobre un protocolo sin estado como HTTP recae sobre nuestra aplicación recordar la cultura especificada por el usuario entre las distintas peticiones.

Entonces tenemos clara la misión:

Mostrar los elementos de la UI acordes a la cultura que el usuario especifique.

Suena fácil, no? Pues lo es, si somos un poco cuidadosos…

(Por cierto, os dejo al final del post el código de la solución para que os lo podáis descargar y probar.)

1 – Estableciendo las bases, recursos a los ficheros de recursos.

Vamos a ir realizando un ejemplo paso a paso para evitar perdernos:

  1. Creamos un nuevo proyecto ASP.NET MVC Web Application
  2. Incluimos en el proyecto la carpeta de App_GlobalResources
  3. Incluimos un par de ficheros de recursos de acuerdo a la configuración de recursos por idioma que deseamos incluir. 

    La convención de nomenclatura de los mismos dice que la primera parte del archivo es el nombre base. La segunda especifica la cultura (puede también ser solo el lenguaje que la forma). Esta última parte es opcional, entendiéndose como el juego de recursos predeterminado en caso de no exista.

    Es responsabilidad del .NET Framework enlazar automáticamente (en base a los ficheros de recursos especificados) el fichero adecuado con a la cultura especificada en actual hilo de ejecución.

    Por ejemplo, creamos el fichero predeterminado (en Inglés) y otro para español sin tener en cuenta el país. (MLTest.resx y MLTest.es.resx  (para cualquier cultura con lenguaje español)) 

  4. Incluimos en el conjunto de ficheros de recursos todos los recursos que nuestra aplicación va a necesitar. 
    En nuestro caso solo uno con nombre «GREETING«. 
  5. Incluimos desde una vista ( por ejemplo Views/Home/Index.aspx) la forma de consumir el recurso:

    <%
    =Resources.MLTest.GREETING%>

    Fuertemente tipado, Intellisense, detección de errores en tiempo de compilación…(da gusto verlo!!)

Bueno, pues ya tenernos una aplicación que nos muestra los recursos en base a la cultura del Framework instalado (en el servidor Web en este caso) que se encarga de especificar la cultura del hilo de ejecución.

Ya es algo, pero no es lo que queremos, verdad?

(El que dude que revise la misión que hemos puesto arriba)

2- Estableciendo la cultura del hilo en ejecución

Ya sabemos que debemos establecer la cultura del hilo de ejecución para que el Framework cargue el fichero de recursos adecuado, pero ahora la pregunta es cuando?

Recordar que cada petición empieza de nuevo y no recuerda las anteriores ( HTTP es stateless). Indagando un poco en la MSDN podemos ver que la clase Controller (de la que derivan nuestros propios controllers) de la implementación del MVC de Microsoft especifica dos métodos virtuales que nos van a resultar muy interesantes:

  • OnActionExecuting
    Se ejecuta antes de la llamada a cualquier Action Method.
  • OnActionExecuted
    Se ejecuta después de la llamada a cualquier Action Method. (obvio, no?)

Como debemos de establecer la cultura cada vez que nos realicen una llamada a cualquier action method de cualquier controlador, lo ideal es crear un controlador base del cual hereden todos los demás y sobrescribir en el método OnActionExecuting el mecanismo para restablecer la cultura. Nuestros controladores harán así transparente al resto de la aplicación las particularidades de trabajar con estado. También podríamos usar un atributo aplicado sobre la clase base y en la implementación del atributo especificar que implementa el interfaz IActionFilter si lo queremos hacer un poco mas AOP que OO.

En la implementación que os dejo utilizo un atributo con el que decoro la clase base (Al gusto!!) 

En el ejemplo:

La clase base de los controladores:

[SetCulture] 
public class BaseController : Controller 
{ 
... 
}

Y en la implementación de la clase del atributo programo como establecer la cultura seleccionada en el hilo activo:

public class SetCultureAttribute : FilterAttribute, IActionFilter 
{ 
	public void OnActionExecuting(ActionExecutingContext 
actionContext) { CultureHelper.SetCulture(GetCurrentCulture
(actionContext), actionContext.
HttpContext.Session) } ...

Para almacenar la cultura especificada entre las llamadas podemos emplear diferentes mecanismos, en este ejemplo el flujo de trabajo será el siguiente:

  1. Revisar si tiene alguna cookie de nuestro sitio que especifique la cultura.
  2. Comprobar la variable de sessión de la cultura.
  3. En caso de no disponer de ninguna de las dos informaciones anteriores, preguntar por las culturas configurados en el navegador y presentar la interfaz de usuario en base a la primera coincidencia que se produzca.

En la implementación que os dejo del proyecto podéis consultar los métodos que he creado para realizar dichas acciones, son muy sencillos y podéis modificarlos al gusto.

Los principales métodos son:

  • GetCurrentCulture de la implementación del atributo, que consulta la información previamente almacenada en base al flujo que hemos comentado.
  • CultureHelper.SetCulture que recibe la cultura a asignar y el objeto intrínseco Session Object y carga cultura en el hilo actual de ejecución.

Aquí nos aparece otro problema.(Que raro, eh?)

Si el usuario es la primera vez que accede a la Web no tiene cookie ni session establecida. 

Para intentar que la aplicación sea lo más “inteligente” posible, recogemos del navegador las culturas que tiene especificadas y las cruzamos con una sección especifica del fichero de configuración creada a tal efecto.

Por ejemplo, si el usuario tiene Chino e italiano necesito determinar si mi aplicación dispone un algún fichero de recursos que da soporte a alguno de los mismos. Para ello me creo una section en el fichero de configuración y un handler que lo soporte que especifique una lista de culturas soportadas y su orden de aplicación. (Así vemos también como poder realizar esta tarea.)

Observar que la tarea no es tan sencilla como coger el idioma y asignarlo al hilo y dejar que el Framework resuelva. (si no lo puede resolver que aplique la predeterminada) puesto que si el usuario tiene, entre todos los lenguajes del navegador, uno que tenemos implementado nos lo estaríamos saltando. (Por ejemplo Chino, Italiano, Español, Ruso)

En el fichero de configuración especificamos:

<
configSections>

<section name=«EnabledLanguages» type=«AndoniArroyo.MLTest.
Controllers.Infrastructure.Configuration.EnabledLanguagesSection,
AndoniArroyo.MLTest»
/>

</
configSections>

además incuimos la citada sección:

<!–Especifica el conjunto de culturas con el que trabaja la aplicación. La última es la cultura por defecto–>
<EnabledLanguages>
<Languages>
<add title=«Spanish» code=«es-ES» />
<add title=«English» code=«en-GB» />
</Languages>
</EnabledLanguages>

Para que la aplicación pueda manejar esta section debemos implementar el handler que la maneje:

namespace AndoniArroyo.MLTest.Controllers.Infrastructure.
Configuration { public sealed class EnabledLanguagesSection : ConfigurationSection { [ConfigurationProperty("Languages", IsDefaultCollection = true,
IsRequired = true)] internal LanguageElementCollection EnabledLanguages { get { return (LanguageElementCollection)this["Languages"]; } } } }

Estos lenguajes será los que tendrá en cuenta el método que intenta cargar el lenguaje desde la información recogida del navegador.

Pues ya casi lo tenemos.

Nos queda por ver como el usuario puede explicitamente modificar la cultura con la que desea trabajar en la aplicación. Visto todos lo anterior la cosa es fácil, no? Basta con crear un action method de modificación de la cultura y en la implementación del mismo llamar explícitamente al método de establecer cultura con el parámetro recibido. (CultureHelper.SetCulture pasándole la cultura especificada por el usuario y la referencia al objeto de sesión…)

Recapitulando, hemos visto unas cuantas cosas:

  • Hemos observado los mecanismos de globalización que nos da el .NET Framework y como extenderlos para nuestras necesidades en web.
  • Definido una política de establecer la cultura activa de la aplicación intentando que la aplicación se adapte al usuario.
  • El punto donde cubrir las características de sin estado del HTTP para establecer la cultura especificada por el usuario.
  • Hemos creado secciones personalizadas en el fichero de configuración y hemos visto como manejarlas.

Y como extra lo prometido el ejemplo con todas estas ideas en acción.

Hosting gratuito para pruebas con Microsoft Visual Studio 2010 y Web Deployment Tool (MsDeploy)

La gente de Labs de  discountASP.NET ha abierto dos programas gratuitos para beta testers:

Cito:

1. FREE Sandbox Hosting for testing Microsoft Visual Studio 2010, Web Deployment Tool (MsDeploy) with .NET Framework 4 beta 1
Experience Next-Generation Web Application Packaging and Deployment Using Microsoft Visual Studio 2010 beta 1 and Web Deployment Tool RC1 (MsDeploy) and ASP.NET 4 beta 1.

2. FREE Sandbox Hosting for testing Microsoft Visual Studio 2010, Web Deployment Tool (MsDeploy) with .NET 2.0/3.0/3.5 SP1
Experience Next-Generation Web Application Packaging and Deployment Using Microsoft Visual Studio 2010 beta 1 and Web Deployment Tool RC1 (MsDeploy) with .NET 2.0/3.0/3.5 sp1

Si os interesa poder comenzar a hacer pruebas  podeis consultar más información en  http://labs.discountasp.net/ (todavía quedan cuentas!!)

Fundamentos de la I.A. (Inteligencia Artificiosa??)

Las aplicaciones informáticas (eso si, a golpe de cañon!) van madurando. Ya consiguen, en la mayoria de las ocasiones, hacer lo que dicen que hacen  y comienzan a ser realmente útiles y hasta necesarias. Partiendo de esta base, el usuario, como es lógico, desea que la aplicación sea más y más eficiente. Demanda ciertas características asociadas tradicionalmente con lo que denominamos «inteligencia». Que el software no solo responda de manera determinista, sino que sea capaz de ayudarle, de preveer sus necesidades con antelación y responder con reflejos a la realidad del día a día.

De nuevo, la pelota está en nuestro tejado…(la de los desarrolladores de software, no mires hacia arriba!!)

Nuestras aplicaciones, independientemete de la funcionalidad que cubran, deben comenzar a adoptar dichas caracteríaticas puesto que será una cualidad excluyente a plazo medio. Es fácil de decir, pero no tan sencillo de transformar en instrucciones que admita un compilador… Por ello vamos a analizar algunas de las características que debe cumplir un software para poder decir que es «inteligente» y a que problemas comunes se deben enfrentar independientemente del campo en el que se apliquen.

Haciendo un poco de historia, hacia 1950 parecía que la mecanización de la inteligencia estaba a tiro de piedra pero todavía más de 50 años después no hemos conseguido interiorizarla a nivel general. ¿Existirá alguna razón oscura para no poder lograr alcanzar esa misteriosa meta? Realmente no hay quien sepa donde está la raya divisoria entre la conducta inteligente y la no-inteligente (pensar que exista una raya puede ser una error en si mismo) Lo que si sabemos es que existen algunas características que denotan inteligencia:

  • Responder con mucha flexibilidad a las situaciones.
  • Sacar provecho de circunstancias fortuitas.
  • Hallar sentido en mensajes ambiguos o contradictorios.
  • Reconocer la importancia relativa de los diferentes elementos de una situación.
  • Encontrar semejanzas entre varias situaciones, pese a las diferencias que puedan separarlas.
  • Encontrar diferencias entre varias situaciones, pese a las semejanzas que puedan vincularlas.
  • Sintetizar nuevos conceptos sobre la base de conceptos viejos que se toman y reacomodan de nuevas maneras.
  • Tener ideas novedosas.
  • (Ahí queda eso…)

Existe aquí una paradoja, puesto que los ordenadores son por naturaleza máquinas inflexibles y recae sobre el software simular estas características. Los expertos en I.A. crean gran cantidad de reglas inflexibles para conseguir que las máquinas sean flexibles. Dichas reglas deben estar organizadas en diferentes niveles, Tiene que haber reglas «llanas«,» metareglas» con las que modificar las reglas «llanas» y probablemente «meta-metareglas» con las que modificar las «metareglas«…(¿Hasta donde?)

La razón de tantas reglas que operan a tantos niveles distintos es que el ser humano (que asumimos posee inteligencia) se enfrenta cada día a millones de situaciones distintas, de diferentes tipos. En ciertas ocasiones nos servirán las reglas «llanas«, en otras ocasiones deberemos aplicar un conjunto de reglas «llanas» modificadas o ajustadas por ciertas «metareglas«. En otras ocasiones, sin embargo, deberemos crear nuevas reglas a partir de las existentes enriqueciendo así el conjunto disponible. En el meollo de la inteligencia hay, sin duda, extraños bucles fundados en reglas que directa o indirectamente se modifican a si mismas.

Aunque la complejidad de nuestro entendimiento parece a veces tan abrumadora que el problema de entender nuestro inteligencia parezca no tener solución. Pero tengamos fé. Se han dado pasos hacia su resolución y sin duda se darán más, es cuestión de trabajo y tiempo!!

8 maneras de cargarte la metodología de un plumazo!!

No es fácil implantar una manera común de desarrollar proyectos de Software. Cada maestrillo tiene su librillo y no siempre nos es fácil adaptarnos al mínimo común necesario para trabajar en equipo de manera orquestada.

Por contra, lo que sí que es realmente fácil , es dinamitar el camino andado. Hace falta muy poco para saltarse alguna que otra regla y echar abajo lo ganado con tanto esfuerzo. Existen algunos puntos claves en los que los equipos somos especialmente propensos a ceder, veamos algunos…

(*Hablando en SCRUM)

  1. No preparar suficiente Product Backlog para que el equipo adquiera prespectiva del proyecto.
    Aunque parezca mentira a los desarrolladores nos gusta saber qué leches estamos programando. De hecho las mejores propuestas de mejora de las aplicaciones surgen, al menos en las primeras fases del proyecto, del propio equipo de desarrollo. Para poder aprovechar toda esa energía/sinergia los desarrolladores deben poder hacerse una idea global del proyecto.
  2. No profundizar lo suficiente el el Sprint Planning Meeting por cansancio o falta de concrección en la exposición del Product Owner.
    La reunión previa en cada sprint permite al equipo hacerse una idea lo más concreta posible de las funcionalidades que más valor aportan al proyecto. Nos permite alinearnos con las necesidades del cliente de tal forma que todos aunemos esfuerzos en la misma dirección. También permite mitigar los riesgos e identificar sorpresar antes de asumir un compromiso. Un buen hábito que no siempre se realiza es el de poner una meta al sprint ( por ejemplo “Disponer del sistema de automatización de informes” ) que identifique la situación ideal al final del mismo y ayude al desarrollador a responder preguntas que le “tienten” por el camino. (¿Es esto importante para la meta del sprint?)
  3. Falta sistemáticamente al Daily Scrum o no respetar sin aviso las pocas liturgias que especifica SCRUM.
    Una de las características que hace a SCRUM “medio” bala de plata tan demandada por los desarrolladores, es las pocas imposiciones que propone. De éstas, una de las más importantes, es la de realizar una pequeña reunión diaria en al que cada miembro del equipo explica que ha hecho el día anterior, que impedimentos se ha encontrado y que pretende hacer en el mismo día de la reunión. Este Daily Scrum es el que da jabón al equipo y permite que todo el mundo este al día del avance, evitar duplicar batallas…
  4. Estancar conocimiento asumiendo un mismo desarrollador todas las Sprint Backlog Item de un Product Backlog Item.
    Es importante que nadie sea imprescindible. Que todos los miembros del equipo desarrollen tareas de todos los Product Backlog Items permite evitar que se creen “Reinos de Taifas” y estandariza el código. Además los equipos de desarrollo con un poco de verguenza torera se igualan por el mejor, lo que permite que se produzca aprendizaje por el camino, mejorando la calidad final del proyecto.
  5. Inventarse tareas sobre la marcha o modificar las existentes bajo demanda.
    Cuando un equipo de SCRUM asume un compromiso con el cliente a través de un sprint, dicho compromiso es inmutable por ambas partes. Es por esto que los sprints son tan cortos, para permitir reorientar el proyecto entre sprints.
  6. Intentar esconder las desviaciones o sufrir el “sindrome del investigador“.
    Si existen desviaciones, lo mejor es saberlo y ser consciente de las causas que las han provocado. En la mayoría de ocasiones dichas desviaciones se pueden justificar y son el argumento principal para mejorar los procesos del equipo. Otro de los aspectos que debe afrontar cualquier metodología es lograr una adecuada visibilidad. Esta característica es la que debe permitir permite que los StakeHolders conocozcan la situación del proyecto. Adoptar una visibilidad adecuada permite detectar las desviacioes de manera temprana así como planificar las acciones orientadas a corregirlas. Como equipo debemos ser capaces de justificarlas y transmitir los motivos a los StakeHolders adecuados, así como las acciones y planes creados. Suele ser un buen hábito, especificar a nivel de Product Backlog Item las condiciones de aceptación, en las cuales se especifican las poscondicones necesarias para que una historia pueda darse por terminada. Por supuesto, deben cumplirse todas para que se pueda dar por finalizada.
  7. No retroalimentar Sprint Backlog Items después de realizarlos.
    Es verdad que siempre vamos con prisa, que existen muchas tareas y todas las excusas que quieras poner, pero para poder decir “Hecho” (y hecho es hecho!!) cada desarrollador debe actualizar como parte de la tarea el estado de los Sprint Backlog Items asociados. Mantener al día dicha información nos permite, analizar las desviaciones y observar la tendencia del sprint y el producto. Colateralmente nos ayuda a ganar y mantener la visibilidad del proyecto manteniendo a los diferentes StakeHolder lo más al día posible.
  8. Evitar las Sprint Retrospective o demostrar falta de compromiso.
    En SCRUM la unión y el compromiso del equipo es clave puesto que todos los miembre del mismo interactuan ampliamente con los demás. El Sprint Retrosprective es la liturgia clave para recibir feedback del mismo y aumentar la unión y sentimiento de grupo. Estas reuniones pueden mejorar mucho los procesos afinando el día a día del equipo, identificando los posibles cuellos de botella y planificando como evitarlos.
    Como siempre, la clave es la constancia, no ceder al desaliento y aplicar las técnicas espartanas de confianza en tus compañeros de equipo. Solo así se puede lograr el “milagro” de echar a andar y mantener una forma de trabajo metodológica.

Como siempre, la clave es la constancia, no ceder al desaliento y aplicar las técnicas espartanas de confianza en tus compañeros de equipo. Solo así se puede lograr el “milagro” de echar a andar y mantener una forma de trabajo metodológica.

Como incluir un fichero en el resultado de una prueba unitaria en Visual Studio 2008

Existen ocasiones en las que nos puede interesar que una prueba unitaria incluya un determinado recurso. Esto ocurre cuando el código que deseamos testear cuenta con la existencia , por ejemplo, de un determinado fichero de texto, una hoja de cálculo o una Service-based Database (.mdf)

Como sabeis, el resultado del proceso de test genera una nueva carpeta (TestResults) donde incluye el resultado de cada generación. Si dicho resultado cuenta con una referencia relativa (la mejor manera de hacerlo) hacia un recurso pues ya la tenemos liada…

Pero como siempre (o casi) la solución es más facil de lo que parece. Existe un decorador especialmente creado para esta necesidad. Basta con colocar sobre el método que deseamos incluya el recurso el item de despliegue de la siguiente manera:

[TestMethod()]
[DeploymentItem(@».fichero.xls»)]

public int EjemploTest()
{



(. si está en la raiz claro…)

Por supuesto los más inquietos ya se estan preguntando como evitar tener que incluir este decorador en todos los métodos (especialmente interesante si se trata de una Service-based Database (mdf)).

Pues para esto también existe una facil solución. Basta con incluir el recurso en el ficheroLocalTestRun.testrunconfig dentro del elemento Deployment con la siguiente sintaxis:

[Nombre del proyecto][Nombre del recurso]

y ya podemos quitar el decorador.

Por cierto, si deseais incluir un fichero Service-based Database (mdf) en una prueba unitaria y referenciarlo con una cadena de conexión del estilo: «..AttachDbFilename=|DataDirectory|..» necesitais tenerinstalado el SP1 de VisualStudio 2008. Sin este, la referencia se realiza directamente contra en .Net Framewok y no encontrará el recurso.