miércoles, 12 de agosto de 2009

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…

lunes, 10 de agosto de 2009

¿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…

lunes, 3 de agosto de 2009

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.


martes, 28 de julio de 2009

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"," metarreglas" 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!!

miércoles, 6 de mayo de 2009

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.

Publicado originalmente en Synergos