Archivos de la categoría tips

Empresa ágil: ¿Cómo construimos el caso de negocio?

Hace unas semanas, un cliente que deseaba impulsar la transformación organizacional en su empresa (un banco de los tres más importantes de su país), nos dijo que necesitaba un “caso de negocio” para respaldar su propuesta ante el directorio.

No es simple establecer un caso de negocio haciendo cálculos sobre resultados que requieren, en la mayor parte de los casos, cambios culturales en la empresa. De todas maneras podemos recorrer algunas observaciones de los últimos tiempos en los que tuve la oportunidad de trabajar en entornos C-Level de grandes empresas.

La intención de este artículo es exponer algunos escenarios que ustedes puedan identificar en las organizaciones en las que trabajan para que puedan sustentar el caso de negocio de una iniciativa de cambio.

Escenario 1: Acumulación de iniciativas

Las áreas de tecnología de las grandes organizaciones, gradualmente y sin notarlo, suelen acumular iniciativas en curso que avanzan en paralelo durante meses o años. Todos ellos necesarios, sin duda.

Estos proyectos ocupan cada vez más capacidad de trabajo de ingenieros, equipos de operaciones, responsables de producto, proveedores, etc. por lo que cada vez queda menos capacidad para el resto de los proyectos, aunque sean de la mayor importancia estratégica. Solo les queda una cada vez más limitada capacidad remanente.

Una empresa que compita en un mercado nacional, regional o mundial debe seleccionar cuidadosamente los proyectos en los que se embarca (sean de tecnología o de negocio) haciendo todo lo posible por segmentarlos de manera que pueda cambiar prioridades en plazos cortos y con resultados intermedios tangibles.

Esto puede parecer una tarea imposible al principio, incluso podemos pensar que hay proyectos que no lo permiten, que los tiempos de proveedores son distintos, etc. Definitivamente no puede cambiarse esa situación de un día para el siguiente, sin embargo esto no es necesario. Solo se requiere que establezcamos como política que no comencemos nuevos proyectos que tomen, por ejemplo, más de tres meses. Si una iniciativa requiere una año, puede completarse en 4 o 5 proyectos.

Podríamos debatir: ¿Cuánto dinero nos cuesta la reacción lenta a las alternativas que nos propone el mercado? ¿Cómo estaríamos en relación a la competencia si fuésemos más rápidos que ellos en reaccionar?

Escenario 2: Silos

Comienzo con un ejemplo a pequeña escala: un responsable de realizar pruebas en software como parte del proceso de desarrollo me dijo que no daba feedback rápido, “en el momento”, al equipo de desarrollo porque tenía que documentar los defectos de la iteración anterior y eso le tomaba mucho tiempo, lo cual no era extraño puesto que el 100% de las entregas requería de feedback y ajustes.

Este es un ejemplo de lo que se llaman silos, es decir, distintas áreas de una organización en las cuales se concentra el conocimiento en un tópico determinado. El trabajo pasa de un área a otra para que cada uno haga lo suyo y siga en la cadena o que vuelva a la etapa anterior (o varios pasos atrás) en caso de que algo no fuese correcto, siempre acompañado del “documento de defectos”.

Los silos se conforman en las organizaciones que no analizar el proceso de trabajo en forma sistémica, es decir, buscando también optimizar la cadena de valor completa.

Las organizaciones maduras (finanzas, salud, seguros, etc) que están siendo pioneras en la adopción de nuevos esquemas de trabajo o de exploración de nuevos campos, optan por conformar equipos independientes y autónomos de manera que el equipo esté conformado con la suficiente diversidad de habilidades que permita llevar completamente a la práctica la idea y evaluar los resultados.

Un ejemplo son los equipos quirúrgicos estables, donde los instrumentadores, anestesistas, cirujanos e, incluso, psicólogos trabajan con un profundo conocimiento producto de años de experiencia conjunta. Hay muchos más.

Para más información sobre este tópico sugiero consultar el modelo Tukman y el trabajo de Patrick Lencioni.

Esta visión no es específica de la cirugía, de las estrategias militares, de equipos deportivos. Por ejemplo, en la industria fintech es usual tener equipos verticales para iniciativas innovadoras o estratégicas.

Podríamos debatir: ¿Cuántas oportunidades de mejora no vemos porque no están todos las personas correctas en la mesa de diseño de un producto? ¿Cuánto dinero ahorraríamos aprovechando estas oportunidades?

Escenario 3: Mejora continua (sistémica)

Continúo con con otra mirada sobre el mismo escenario anterior (Silos).

La conversación comenzó con una consulta para optimizar el proceso de reporte de los defectos en el software pues el mecanismo que estaban utilizando les tomaba mucho tiempo y esfuerzo. Requería documentar y reproducir las condiciones del defecto, captura de pantallas, confección de un documento, crear un incidente en la herramienta utilizada, adjuntar la evidencia, etc.

Investigando un poco sobre el para qué de estos artefactos, llegamos a la conclusión de que eran requeridos para la comunicación entre las dos áreas. El equipo responsable de las pruebas deseaba, genuinamente, mejorar su proceso de trabajo.

Nuevas opciones aparecen en escena cuando analizamos el problema sistémicamente, es decir, con una visión más amplia del proceso completo. En ese caso directamente eliminamos toda la tarea cambiando el mecanismo de feedback por un enfoque just-in-time por el cual la persona daba la mayoría del feedback ante consultas del desarrollador.

Un proceso de mejora continua eficaz debe tomar en cuenta, alternativamente, la versión sistémica y la local, con esta última subordinada a la sistémica.

Una de las formas de visualizar nuestro proceso (al menos la parte del sistema que está a nuestro alcance influir) es construir un value stream map. Esta visualización nos permitirá conversaciones arribar a optimizaciones globales, que no veríamos mirando solo a los subsistemas locales.

Podríamos debatir: ¿Cuánto mejor funcionará la organización si prestamos atención al proceso completo? ¿Son todos los pasos que hoy existen necesarios? ¿Cuánto dinero ahorraríamos aprovechando estas optimizaciones sistémicas?

Conclusión

Espero haber presentado algunos escenarios que pueden resultarles familiares y, por tanto, funcionar como punto de partida de conversaciones y debates.

Estoy convencido de que los marcos de trabajo ágiles o lean no sólo propician ambientes más humanos, sino también más eficaces y eficientes, desde el punto de vista de la productividad , calidad y son más adaptables (una capacidad que las empresas de hoy en día no pueden dejar de lado).

Incluso abrigo la esperanza de que estos tres modestos casos presentados les disparen muchos más, algunos específicos, otros más generales. Ojalá los muevan a generar espacios más humanos y asombrosos en las grandes organizaciones.

¡Nos vemos!

La imágen del encabezado la tomé de este post, que recomiendo leer, en relación al tema del artículo.

Dependencias ocultas entre clientes y servicios

Hace unos días, en una revisión de código, encontré una definición de interfaz de un servicio que no me gustó. No fue inmediatamente evidente para mi pero uno de sus métodos era un code smell.

Esta es la interfaz:

<span style="color: blue;">public interface </span><span style="color: #2b91af;">IIpStsStore</span>{
    <span style="color: blue;">void </span>AddCredential(<span style="color: blue;">string </span>userName, <span style="color: blue;">string </span>password);
    <span style="color: blue;">void </span>RemoveCredential(<span style="color: blue;">string </span>userName);
    <span style="color: blue;">bool </span>CredentialExist(<span style="color: blue;">string </span>userName);
}

El método que me olía mal es el último. Luego de exprimir el cerebro un poco me di cuenta del motivo. Ese método, a mi juicio, propicia un acoplamiento innecesario entre el cliente del servicio y la implementación de dicho servicio.

Si exponemos ese método seguramente el cliente del servicio lo va a usar y no tendremos control de este uso, es decir, no sabremos exactamente cuando van a utilizarlo.

Supongamos que la primera implementación de ese servicio accede directamente al recurso donde se almacenan las credenciales. En ese caso, si el cliente llama a AddCredential() e inmediatamente llama a CredentialExist(), todo funcionará correctamente.

El problema aparecerá cuando hagamos otra implementación del servicio IpStsStore que funcione en forma asíncrona. En ese caso ya no habrá garantía de que la secuencia de métodos mencionada mas arriba siga funcionando.

En definitiva, tenemos un acoplamiento entre el cliente y la implementación del servicio, algo que siempre debe tratar de evitarse, además, como suele ocurrir en estos casos, luego de pensar un poco el diseño, ese método tampoco era necesario, un típico caso YAGNI.

Que nunca falte un registro de actividad en tu aplicación. Nunca.

La semana pasada un cliente me llamó debido a que una de sus aplicaciones recién lanzada estaba un tanto inestable. Quiero compartir hoy con ustedes la recomendación que le di, la mas simple y mas efectiva que recuerdo haber dado.

Mas allá de revisar algunas cuestiones directamente relacionadas con las inestabilidades reportadas por usuarios finales, lo primero que les pedí es que me mostraran los logs para enterarme de que no los tenían.

Hoy no hay excusas para no tener información de este tipo en la plataforma .NET, todos los tipos de aplicaciones (Web, Desktop, Servicios, etc.) proveen un mecanismo centralizado de

Aquí algunos consejos básicos:

  • Registren todas las excepciones (básico)
  • No es necesario utilizar try – catch innecesariamente en todo su código, es suficiente con engancharse en el handler centralizado.
  • Registre información con distinto nivel de detalle (los niveles corresponden a log4net pero los demás utilitarios tienen niveles similares), al menos:
    • ERROR: las excepciones, deje que el framework se encargue de mostrar mensajes, callstacks, etc. También registre errores de formato, de protocolo, etc, aunque también podría utilizarse el nivel WARNING (o WARN).
    • INFO: algunos puntos importantes del funcionamiento de la aplicación tales como el inicio, datos de configuración utilizados, finalización, etc.
    • DEBUG: en esta modalidad puede registrarse información mas detallada del funcionamiento de la aplicación.
  • Configure correctamente el nivel de registro en cada ambiente. Generalmente uso nivel INFO en ambientes de producción (que también registra WARN, ERROR y CRITICAL) y nivel DEBUG en ambientes de desarrollo.
  • Use herramientas sencillas (log4net, NLog) y registre la información en simple archivos de texto. Nunca me resulto cómodo utilizar el registro de eventos de Windows.

Para aplicaciones ASP.NET

<span style="color: blue;">protected void </span>Application_Start()
{
    Error += Application_Error;
}

<span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;">private</span></span><span style="font-size: x-small;"> </span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;">void</span></span><span style="font-size: x-small;"> Application_Error(    </span><span style="color: #0000ff; font-size: x-small;"><span style="color: #0000ff; font-size: x-small;">object</span></span><span style="font-size: x-small;"> sender, </span><span style="color: #2b91af; font-size: x-small;"><span style="color: #2b91af; font-size: x-small;">EventArgs</span></span><span style="font-size: x-small;"> e)

{
</span>
<blockquote><span style="font-size: x-small;">
</span><span style="color: #2b91af; font-size: x-small;"><span style="color: #2b91af; font-size: x-small;">Exception</span></span><span style="font-size: x-small;"> ex = Server.GetLastError();
</span></blockquote>
<span style="font-size: x-small;">
</span>
<blockquote><span style="font-size: x-small;">
log.Error(</span><span style="color: #a31515; font-size: x-small;"><span style="color: #a31515; font-size: x-small;">"Application_Error", ex</span></span><span style="font-size: x-small;">);
</span></blockquote>
<span style="font-size: x-small;">
<blockquote>
Server.ClearError();</blockquote>
}

</span>

Para aplicaciones Desktop

<span style="color: blue;">static void </span>Main()
{
<span style="color: #2b91af;"><span style="color: #333333;">    </span>AppDomain</span>.CurrentDomain.UnhandledException +=
        UnhandledExceptionHandler;

    <span style="color: #2b91af;">Application</span>.Run(<span style="color: blue;">new </span><span style="color: #2b91af;">Principal</span>());
}
<span style="color: blue;">private static void </span>UnhandledExceptionHandler(
    <span style="color: blue;">object </span>sender, <span style="color: #2b91af;">UnhandledExceptionEventArgs </span>args)
{
    <span style="color: blue;">var </span>e = (<span style="color: #2b91af;">Exception</span>)args.ExceptionObject;

    log.Error(<span style="color: #a31515; font-size: x-small;"><span style="color: #a31515; font-size: x-small;">"Application_Error", ex</span></span><span style="font-size: x-small;">);

</span>    <span style="color: blue;">if </span>(<span style="color: #2b91af;">MessageBox</span>.Show(<span style="color: #a31515;">"Reporte este error:\n" </span>+         e + <span style="color: #a31515;">"\n\n¿Desea copiarlo al portapapeles?"</span>,
        <span style="color: #a31515;">"Error en Clasificador"</span>,
        <span style="color: #2b91af;">MessageBoxButtons</span>.YesNo, <span style="color: #2b91af;"><span style="color: #333333;">        </span>MessageBoxIcon</span>.Error) == <span style="color: #2b91af;">DialogResult</span>.Yes)
    {
        <span style="color: #2b91af;">Clipboard</span>.SetText(e.ToString());
    }
    <span style="color: #2b91af;">Environment</span>.Exit(1);
}

Mas informacion:

Azure mejora

Una buena noticia para el sufrido administrador de servicios Azure. El proceso de actualización de un servicio ahora permite realizar la operación en un solo paso: Upgrade.

Hasta hace unos días era necesario seguir el siguiente proceso: a) detener la aplicación; b) borrarla; c) subir la nueva y d) ponerla en marcha.

Aquí se ve la nueva opción:

image

Aquí pueden ver la pantalla que informa sobre el avance del proceso de actualización.

image

Aún hay que esperar varios minutos para que el proceso termine pero al menos puedo dedicarme a otra cosa.

Sean buenos.