viernes, 3 de febrero de 2017

Patrón Observador




Hemos vuelto, esta vez escribo sobre el patrón observador (the observer pattern), este patrón es muy simple y se usa cundo se require que alguien se entere de que algo ha sucedido dentro de otro ámbito, de allí su nombre, veremos un ejemplo sencillo:

Lo primero que se requiere es una interface Observer de quien saldrán las implementaciones que serán los Observadores:

public interface Observer {
    void update();

}

Luego tendremos otra interface Observable que es la que va a implementar nuestra objeto que necesitamos que notifique sus cambios de estado:

public interface Observable {
    public void addObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObservers();

}

Ahora las implementaciones, primero veamos la implementación de Observable:

import java.util.ArrayList;
import java.util.List;

public class Invoice implements Observable {

    
    private String serialNumber;
    
    private String status;
    
    public Invoice(final String serialNumber) {
        this.serialNumber = serialNumber;
        this.status = "new";
    }
    
    public String getSerialNumber() {
        return serialNumber;
    }
    
    public String getStatus() {
        return status;
    }
    
    private List<Observer> observers = new ArrayList<Observer>();
    
    public void markAsPaid() {
        notifyObservers();
    }
    
    public void addObserver(final Observer observer) {
        this.observers.add(observer);
    }

    public void removeObserver(final Observer observer) {
        this.observers.remove(observer);
    }

    public void notifyObservers() {
        for(Observer observer : this.observers) {
            observer.update();
        }
    }


}

Por último las implementaciones de la interfaz Observer:

public class InvoiceStorer implements Observer {

    private Invoice invoice;
    
    public InvoiceStorer(final Invoice invoice) {
        this.invoice = invoice;
        this.invoice.addObserver(this);
    }
    
    public void update() {
        System.out.println("Guardando cambio de estado de la factura: " 
                + this.invoice.getSerialNumber() 
                + " a " + this.invoice.getStatus());
    }
    
    public String getInvoiceSerialNumber() {
        return invoice.getSerialNumber();
    }

}

public class InvoiceStatusChangeNotifyer implements Observer {

    private Invoice invoice;
    
    public InvoiceStatusChangeNotifyer(final Invoice invoice) {
        this.invoice = invoice;
        this.invoice.addObserver(this);
    }
    
    public void update() {
        System.out.println("Notificar pago de factura: " + invoice.getSerialNumber());
    }
    
    public String getInvoiceSerialNumber() {
        return invoice.getSerialNumber();
    }

}

Tenemos un test para probar la funcionalidad hecha:

import java.util.UUID;

import org.junit.Assert;
import org.junit.Test;

public class InvoiceTest {
    
    @Test
    public void markAsPaid(){
        String serialNumber = UUID.randomUUID().toString();
        Invoice invoice = new Invoice(serialNumber);
        InvoiceStorer storer = new InvoiceStorer(invoice);
        InvoiceStatusChangeNotifyer notifyer = new InvoiceStatusChangeNotifyer(invoice);
        invoice.markAsPaid();
        Assert.assertEquals(serialNumber, storer.getInvoiceSerialNumber());
        Assert.assertEquals(serialNumber, notifyer.getInvoiceSerialNumber());
    }

}
La salida del test es:

Guardando cambio de estado de la factura: db1a5606-2aad-475c-b4af-bf59f03975d4 a new

Notificar pago de factura: db1a5606-2aad-475c-b4af-bf59f03975d4

Ahora si vamos a ver lo que sucedió.

Lo primero es que los Observers al inicializarse se "registran" haciendo la llamada al método addObserver de la clase Invoice, este método llena una lista de observadores a la que al momento de que se actualiza su estado (método markAsPaid) les notifica del cambio hecho.

Cuando los observadores son notificados hacen uso de la instancia de su observable para hacer su trabajo, por ejemplo el InvoiceStorer se encargará de guardar el cambio de estado en la base de datos, mientras que el InvoiceStatusChangeNotifyer se encargará de enviar una notificación por correo electrónico informando del pago de la factura.

Como vemos, esto se pudo haber hecho en sólo el método de markAsPaid pero usando el patrón observador se puede hacer una mejor separación de responsabilidades.

martes, 18 de octubre de 2016

Que cosas hacen de Scrum?


Este post ya tiene rato en la congeladora, así que espero recordar bien lo que quería transmitir con él en ese momento de mi vida.

Hace unos meses alguien me hizo esta pregunta, ¿Qué hacen de Scrum?, la cuál me llamó mucho la atención ya que esta es una pregunta que normalmente hace alguien que no conoce de metodologías ágiles de desarrollo de software, mucho menos de Scrum, normalmente estas personas sólo han oído hablar, han leído del tema o los han "obligado" a la mala a "usarlo", por eso es que a ellos les hace sentido esa pregunta.

A parte de esto lo que yo leo en esta pregunta es desinterés y rechazo sobre el framework en sí ya que aunque se ha tenido el contacto no se ha tenido las ganas de de verdad conocerla y poder ver mas allá de su "uso".

Pero bueno, en ese momento puse mi cara de what? la sangre me hirvió y me dieron ganas de platicarle lo que realmente significa y que no es algo que se "usa", sino algo que se interioriza y se vive hasta el punto de convertirse en uno de tus principios de vida (ya se que suena muy mamón, pero de verdad que así es) pero pude contenerme y lo que me salvó fueron las siguientes preguntas de esta persona, las cuales me ayudaron a desafanarme del tema muy rápidamente, ¿sólo hacen junta diaria y ya verdad? y ¿también hacen sprints no? a las cuales mis respuestan fueron "heee (dudando) aaa si, solo eso hacemos", ya se que estuvo mal, pero en ese momento no quería entrar en discusiones ni detalles, solo me quería desafanar.

Gente, scrum no se usa, es un modo de ver el mundo, ágil en general lo es, si recordamos uno de los principios ágiles que dice:
"At regular intervals, the team reflects on how 
to become more effective, then tunes and adjusts 
its behavior accordingly"
Nos habla sobre lo que en scrum conocemos como retrospectivas, esto en lo personal me ha ayudado mucho a mí en vida de portero, cada vez que acaba un partido paso por mi mente una y otra vez los goles que me metieron y así visualizar que es lo que hice mal y que pude haber hecho en ese momento que me hubiera ayudado a que el balón no terminara en las redes. Parece algo simple, pero así es, y este es sólo un ejemplo de como es que yo "uso" scrum en mi vida.

Ahora, ven como es que esto se vuelve parte de tus principios, en este caso, la reflexión y la mejora continua.

A mis lectores, en verdad les recomiendo que lean, escuchen, vean, se involucren y entiendan lo que scrum y ágil en general les puede dejar en sus vidas, por la red rondan muchos sitios donde no sólo hablan de ágil en desarrollo de software, sino en la vida cotidiana por lo que aún si no te dedicas a la profesión de los 0's y 1's estaría muy bueno que le des una pasada, al menos para que no se te ocurra preguntar ¿Que cosas hacen de Scrum?.

Un abrazo a todos.

lunes, 5 de septiembre de 2016

Reduce regresando un objeto


La semana pasada escribí acerca de algunas funciones útiles en javascript, una de ellas es mas interesante de lo que parece, ésta es la función reduce, en ese post comentamos que lo usamos cuando tenemos que generar un sumarizado de un arreglo, en ese momento hicimos el conteo (sumarizado) de cachorros y de adultos, en sí esta forma es útil, pero a veces lo que queremos no es un sumarizado numérico, sino crear un objeto y que él sea el sumarizado.

Reduce nos sirve también en este caso de uso ya que la función también puede regresar el sumarizado como un objeto, no solo como un entero.

Otra cosa que mencioné es que no me había tocado usar alguna de estas funciones, pero ya en esta semana que pasó me tocó usar reduce, el caso de uso fue el siguiente:

Tengo un arreglo de bancos con los bines de tarjetas de crédito, en este caso lo que necesitaba es un arreglo de los bancos que tengo en la lista, por lo que usé la función reduce para "reducir" (sumarizar) el arreglo de bines de bancos en un arreglo de bancos, el código es como sigue:

var bines = [{"bank":"banco1","bin":"111111"},
     {"bank":"banco1","bin":"122222"},
           {"bank":"banco1","bin":"133333"},
     {"bank":"banco1","bin":"144444"},
          {"bank":"banco2","bin":"211111"},
     {"bank":"banco2","bin":"222222"},
     {"bank":"banco2","bin":"233333"},
     {"bank":"banco3","bin":"311111"},
     {"bank":"banco3","bin":"322222"}];

var reduced_banks = bines.reduce(function(banks, bin) {
isAlreadyAdded = banks.find(function(bank) {
return bank == bin.bank;
})
if(!isAlreadyAdded)
banks.push(bin.bank);
return banks;
}, []);
console.log(reduced_banks);

lo que sale a la consola es:


[ 'banco1', 'banco2', 'banco3' ]

Esto es, el listado de bancos.

Ahora, explicando un poco lo que sucede, tenemos un arreglo de bines en el que se repiten los bancos y lo que queremos es sólo el arreglo de bancos, lo que hacemos es usar la función reduce mandándole una función que recibe el objeto contenedor del sumarizado (banks) y el elemento actual de la lista original (bin), enviándole también a la función reduce un arreglo vacío como último parámetro ([]) que es el valor inicial de banks, luego reduce aplica a cada elemento del arreglo bines la función que le enviamos como primer parámetro donde lo que hacemos es buscar en el arreglo de bancos (banks)
si ya existe el banco del elemento en el que estamos de bines y si no ha sido agregado antes se agrega al arreglo banks (objeto simarizador). Como ven, también find es aplicado sobre un arreglo, en este caso banks y lo que hace es iterar sobre cada elemento del arreglo y a cada elemento le aplica la función  que le mandamos como parámetro y que regresa true si el arreglo ya contiene banco del elemento actual de bines.

Espero que este ejemplo sea didáctico en el uso de reduce y find, en este ejemplo el objeto sumarizador es un arreglo, pero bien puede ser cualquier otro tipo de objeto.

viernes, 26 de agosto de 2016

Algunas funciones útiles en javascript

Esto de cambiar de trabajo es muy interesante, la verdad es que uno está acostumbrado a cierto ritmo y al cambiar de trabajo tu día cambia mucho desde tomar otra ruta para llegar a la oficina, levantarte en un horario distinto hasta conocer gente distinta, reencontrarte con los antiguos camaradas, regresar a programar activamente y bueno pues como en todo encontrar problemas distintos a los ya habituales, un ritmo de trabajo distinto, un negocio distinto y cosas nuevas por aprender.

Dentro de estos cambios me ha tocado entender AWS, lo que ofrece y como manejar lo que tiene (en mi primer semana instalé dos veces en producción), algo de spring que ya tenía un poco empolvado y lo que más me ha costado, reencontrarme con los html, javascript y css, esos fueron mis amigos en mi primer trabajo hace mas o menos 10 años y desde entonces no me había tocado trabajar activamente en el front end de aplicaciones web de esta manera pues en Tralix me la pasé más con GWT, un poco de echo2 y muy poco de struts.

Y como parte de mi aprendizaje he estado viendo algunas cosas en javascrip que me llamaron la atención, en particular las funciones find, filter, map y reduce (que aún no he ocupado pero que ya son parte de mi toolbox) y de esas funciones es de lo que quiero hablar en este post. Comencemos con el arreglo definido de la siguiente manera:

mascotas = [
{
'nombre'  : 'max',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '3',
'sexo'    : 'macho'
},
{
'nombre'  : 'yoshina',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '5',
'sexo'    : 'hembra'
},
{
'nombre'  : 'luneta',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '4',
'sexo'    : 'hembra'
},
{
'nombre'  : 'simba',
'especie' : 'perro',
'raza'    : 'dálmata',
'edad'    : '1',
'sexo'    : 'macho'
}
]

Find

La función find nos sirve para encontrar un elemento en un arreglo, por ejemplo si queremos encontrar a max dentro del arreglo lo que tenemos que hacer es:

max = mascotas.find(function(mascota) {
return mascota.nombre == 'max'
})
console.log(max)

y lo que nos va a imprimir en la consola es a max.

Filter

La función filter la usamos para obtener un sub arreglo del arreglo original, por ejemplo si queremos encontrar a todos nuestros perros machos lo que tenemos que hacer es:

machos = mascotas.filter(function(mascota) {
return mascota.sexo == 'macho'
})
console.log(machos)

en este caso nos imprimirá en la consola un sub arreglo conteniendo a max y a simba.

Map

La función map se usa cuando queremos transformar un arreglo en otro, esta es una función muy útil cuando se trabaja en un cliente de servicios REST ya que normalmente lo que el servicio nos trae son cosas generales y tal vez nosotros no queremos operar sobre todos los datos, sino sobre sólo algunos, espero esto no sea confuso, pero bueno, para que quede mas claro vamos a transformar nuestro arreglo de mascotas en un arreglo de edades de la siguiente forma:

edades = mascotas.map(function(mascota) {
return mascota.edad
})
console.log(edades)

Lo que nos imprime en la consola es el arreglo de las cuatro edades de nuestros perros (transformamos un arreglo de mascotas a un arreglo de edades).

Reduce

La función reduce normalmente la ocupamos cuando queremos generar un "sumarizado" o un resultado "agregativo" (jeje no supe como decirlo) sobre un arreglo, para que sea mas claro veamos el ejemplo:

cachorros = mascotas.reduce(function(total, mascota) {
if (mascota.edad <= 1)
return total +1
else 
return total
}, 0)
console.log(cachorros)

la salida a la consola que obtenemos es la cantidad de cachorros que hay en nuestro arreglo (los que son menores o igual a 1 año de edad), y la forma en que opera es que va iterando el arreglo, para cada elemento checa la edad de la mascota y si es un cachorro suma 1 al total, por cierto ese 0 "cero" extraño que se ve al final de la llamada a la función reduce es el valor inicial del total.

Lo bonito de esto es que muchas de estas funciones existen dentro de prácticamente todos los lenguajes funcionales y nos ayudan no solo en la programación del front end en javascript.

Otra cosa a hacer notar es que todas estas funciones reciben como uno de sus parámetros una función, esto las hace muy poderosas y reusables ya que por ejemplo si quieres obtener a los adultos (en el ejemplo del reduce) lo único que tienes que hacer es cambiar a función que recibe el reduce como parámetro, lo que se hace es sacar la función a por ejemplo:

cachorros = function(total, mascota) {
if (mascota.edad <= 1)
return total +1
else 
return total
}

y tener otra función:

adultos = function(total, mascota) {
if (mascota.edad > 1)
return total +1
else 
return total


y pasar uno u otra al reduce:

numero_cachorros = mascotas.reduce(cachorros(total, mascota), 0)

o

numero_adultos = mascotas.reduce(adultos(total, mascota), 0)

Con esto se ilustra una de las bondades de la programación funcional, el poder enviar funciones como parámetros.

Este post nos sirve como capítulo introductorio a la programación funcional, de la que estaremos hablando poco a poco.

sábado, 6 de agosto de 2016

Single responsibility principle (parte 2)




Esta es la segunda parte de mi post sobre SRP, en la primer parte comentamos que es y una de las formas en que nos afecta, esta vez hablaremos de otra forma en que nos afecta y veremos algo de código, así que agaaaarrrrrrense...

Primero una de las cosas que hay que tomar en cuenta es que el software y en particular las clases en POO son una representación del negocio, por lo que es una forma muy habitual de "encapsular" ese negocio el crear una clase por ejemplo EmployeeBusiness en donde se mete todo lo que tiene que ver con el empleado, a simple vista esto es correcto ya que coo decimos, representa el negocio, pero el problema es que lo estamos viendo desde el punto de vista de la entidad y ahí es donde esta jodido este asunto, que va a pasar con esta clase?

1. Va a crecer enormemente dado todas las operaciones que se pueden hacer con el empleado.
2. Va a tener un montón de dependencias por lo que se corre el riesgo de un alto acoplamiento.
3. Va  tener muchos motivos por los cuales puede cambiar, y acá es donde se rompe este principio.

Pero entonces como CREO YO que se deben de hacer las cosas? bien, pues afectivamente separar bien las cosas de acuerdo al negocio, por ejemplo una clase para manejar las vacaciones del empleado, otra para el cálculo de su nómina, otra para cuando se da de baja y así, como se dan cuenta la separación es efectivamente por negocio y nos damos cuenta ya que cada una de estas clases tiene un "stakeholder" específico y no necesariamente el mismo, por ejemplo la gente de RH es el "encargado" de las modificaciones a las reglas de vacaciones, la gente de nómina es el "encargado" de las modificaciones a las reglas de cálculo de nómina y así sucesivamente. Así tendremos las siguientes características en cada clase:

1. Se hacen pequeñas ya que cada una sirve a un propósito my específico.
2. Las dependencias disminuyen al sólo tener las necesarias para realizar su trabajo.
3. Sólo tiene un motivo por el cual va a cambiar y no sólo un motivo, sino un solo rol que dicta que cambia cómo y porqué.
4. Es mucho más fácil de probar.
5. Cumple con una alta cohesión.

Un ejemplo de este principio lo pueden ver en mi post de patrón decorador para validar en el que las responsabilidades están muy bien definidas y son totalmente independientes cada una de las clases.

Ya se que les prometí código en este post, pero creo que la explicación es lo suficientemente buena como para convencerse de que vale la pena que nuestras clases cumplan con este principio y les dejo la liga mi post donde pueden ver la aplicación de una forma muy clara y sencilla.



sábado, 23 de julio de 2016

Single responsibility principle (parte 1)

Este es el primer post para comentar a cerca de los principios SOLID, en esta ocasión nos enfocaremos en el principio de Single responsibility o Responsabilidad única (la S en SOLID), como ya comentamos en un post anterior los principios de son ciertas características (de diseño) que el desarrollo de software orientado a objetos debe de cumplir para que se diga que está bien estructurado y que ayuda a que el codigo sea entendible y por ende matenible, así que eso es lo que abordaremos en este post enfocandonos al principio de responsabilidad única.

Bien se dice por alli que el que mucho abarca poco aprieta, pues bien, esto llevado a la programación orientada a objetos es éste principio, en el que se describe que una clase debe de tener una única responsabilidad y no más que esa, como nos damos cuenta de que nuestra clase cumple con ella? pues esto es coo muchos dice, cumple con ella si es que tiene una única razon por la que tiene que cambiar, si es así entonces se dice que tiene una sola razón de ser y si esa razón de ser cambia por alguna razón entonces la clase debe de cambiar, pero sólo por eso deber de hacerlo.

Ahora este principio no solo se refleja en clases, sino en métodos, variables, paquetes, componentes y hasta sistemas, como es esto? pues bien, una variable debe de existir para solo una cosa, esto nos lleva a un buen nombramiento de la variable y esto es parte de clean code, esto es si se tiene una variable por ejemplo nombrada x que es de tipo Integer, en si el nombre no nos dice nada, por lo que estaremos tentados a usarla para lo que se nos antoje dentro de nuestro sistema, pudiendo usarla para almacenar la edad de un empleado, como índice para iterar el arreglo de percepciones del empleado (lo bueno es que ese arreglo no es muy grande jeje), etc. esto nos lleva a problemas muy graves de mantenimiento del código, lo que provoca que existan bugs, lo que provoca que nuestros clientes se quejen de lo que hacemos, lo que provoca que la empresa pierda dinero (o reputación), lo que provoca que se pierda la confianza en el desarrollador, lo que provoca que nos despidan, lo que provoca que nos atrasemos en el pago de nuestro lujoso carro (que sacamos a crédito augurando una buena carrera) lo que provoca... bueno, creo que ya di a entender el punto y todo esto por nombrar mal una variable, pero que pasa si a esa variable le nombramos employeeAge, pues ya sabemos que esa variable representa a la edad del empleado y estaremos menos tentados a usarla para almacenar algo distinto a la edad del empleado.

Si se dan cuenta, esta variable tiene una única responsabilidad que es almacenar la edad del empleado, ahora, esto aplica igual para métodos, éstos tambien deben de tener una única responsabilidad, por ejemplo el método que calcula los dias de vacaciones que tiene un empleado, esa es su responsabilidad, no la de ir a la base de datos por las reglas de vacaciones configuradas por el departamento de RH, ni ir a la base de datos para obtener la fecha de ingreso del empleado, este método sólo debe de hacer el cálculo y ya, no más que eso, en cuanto a una clase, pues como ya lo han de intuir, aplica igual ya que ésta solo se debe de encargar de algo en específico y delegar lo más que se pueda a otras clases que podrá usar o desde las que podrá ser usada para lograr un objetivo más general, en paqutes pasa lo mismo por ejemplo un paquete que tega las clases necesarias para la sección de nómina de los empleados que incluye clases para el cálculo, para extracción de datos, excepciones probables y demñas cosas que tienen que ver con la nómina, mas arriba, al sistema completo, que tiene que tener una resposabilidad única que es manejada por la gente de negocio de nuestra organización.

Últimamente se ha escuchado mucho sobre los microservicios, ellos son un ejemplo de responsabilidad única a nivel de deployable y de sistema pues de lo que se tratan es de que cada parte sea los mas independiente posible y tiene una responsabilidad muy específica llegando incluso a ser instalada de forma independiente a las demás características del sistema completo, teniendo su propia base de datos, su propio ambiente, tal vez hasta estar hecho en un lenguaje distinto a los demás y estar instalado en un servidor virtual en la india.

Pues bien, hasta acá le dejamos en la primer parte del Single responsibility principle, espero que se haya entendido de que se trata y que se puede extender mas allá a sólo clases.

En el siguiente post hablaremos de forma mas puntual de este principio con código de ejemplo y toda la cosa.

domingo, 10 de julio de 2016

La meta

Hace tres semanas tenía pensado escribir acerca de La meta (el libro que acababa de leer) pero al empezar a escribir vi necesario decir cómo es que ese libro llegó a mi y eso me llevó a escribir sobre el reto que me había puesto de 1 libro por mes, así que borré lo poco que tenía y empecé a escribir acerca del reto, luego pensé que era difícil que entendieran ese reto si no hay un contexto, así que decidí empezar dando ese contexto y borré lo poco que tenía del reto y así fue que salió el post de la lectura, luego, la siguiente semana no escribí debido a que anduve algo enfermo de la garganta y luego la semana pasada acabó mi ciclo en Tralix, por lo que decidí escribir un poco sobre unos pensamientos que me llegaban mientras me alejaba del lugar que fue como mi hogar por poco mas de 8 años. Así que ahora si... hablaremos de "la meta".

La meta es un libro que llegó a mí por que Ana me lo recomendó, en ese momento dije "va, solo acabo el que tengo ahorita leyendo, luego el que tengo ya formado y ya luego lo empiezo, pero va..." así fue, terminé el libro 1 de caballo de Troya, luego the pragmatic project automation y empecé con la meta, cabe mencionar que tengo la mala maña de que cuando empiezo un libro lo leo desde la portada hasta la contraportada y me llamó la atención el tipo de comentarios que ponían en las primeras secciones, eso me dio curiosidad y ánimo para leerlo.

Solo haré un pequeño resumen del contenido, los que están en Tralix pueden ver con Ana si lo tiene disponible para préstamo, los que no, lo pueden conseguir en Amazon el el título de "LA META" o "THE GOAL" (para la versión en inglés). Este libro cuenta una "novela", donde se narran 3 meses de la vida del encargado de una planta manufacturera que a su vez es esposo, padre e hijo, que como muchos de nosotros tiene problemas por todos lados, es decir, ya no ve lo duro, sino lo tupido, Alex es en cargado de una planta desahuciada a desaparecer dados los malos resultados que da a la compañía, estos problemas acarrean a Alex a problemas con su pareja, de la que se separa por un tiempo, al inicio no sabe que hacer para salvar la planta hasta que recuerda una plática con su ex profesor de física de la universidad acerca de "la meta", luego él junto con algunos compañeros de trabajo y con ayuda de Noha (su ex profesor) van viendo cuales son los problemas de la planta y van viendo como solucionarlos llegando al final a ser una planta exitosa y Alex a ser ascendido, pero lo interesante no es esa parte de la novela, sino los conceptos que se describen y como llegan al éxito, así como el cambio de paradigma que proponen y es de esto de lo que me gustaría hablar en este post.

Primero, al leerlo me vi reflejado en Alex por que su vida personal reflejaba la mía de hace unos años y que creo que la mayoría de nosotros tenemos cuando tenemos que dedicarle tiempo al trabajo que debería de ser dedicado a nuestras familias y que llegas a la casa y en tu mente están los problemas del trabajo, buscando soluciones y no dejando disfrutar la vida fuera.

Luego habla sobre la meta de una compañía que es muy difícil de captar pero que al final de cuentas es ganar dinero, bajo eso como meta cada compañía tiene una forma distinta de llegar a ganar dinero, es allí donde se ve la dirección, las estrategias de cada sección, todo enfocado hacia eso, por lo que lo que sea que se haga debe de estar encaminado a esa meta, pero el problema es que muchas veces la forma de esa estrategia no es la adecuada, en el caso de la compañía de Alex, miden la productividad por sección, lo cual como se ve allí no es lo mejor, lo mismo pasa en muchas otras empresas, incluidas las de desarrollo de software donde a leguas se ve que no es la mejor forma de medir, ya muchos en ésta área han escrito de esto, llegando a estar de acuerdo en que la productividad de un desarrollador no se basa en las líneas de código que genera, o el tiempo que pasa sentado frente a su monitor, o la cantidad de bugs que resuelve, ni siquiera en la cantidad de features que genera... se debería de basar en la cantidad de dinero que ese nuevo feature le entrega a la compañía o en la cantidad de dinero que al solucionar el bug le está ahorrando a la compañía, es decir, en el valor de negocio EFECTIVO. Es aquí donde el concepto de contabilidad de costos tuerce el rabo, ya que no mide de esa forma, sino (en el caso de desarrollo de software) a cuanto tiempo le dedicas a solucionar un bug o a que hay mas? bugs o features? y eso  al final no es una métrica que ayude a "la meta".

Otro concepto interesante que mencionan en el libro es la fluctuación estadística, que es la variación que hay en hacer una tarea, por ejemplo el empleado A tarda 5 minutos en hacer una tarea, mientras que el empleado B tarda sólo 3 y el empleado C tarda 6, la fluctuación estadística es esa variación, que en manufactura puede llegar a ser algo estándar y controlable de alguna manera, pero en desarrollo de software es enorme debido a que es un proceso mas artesanal, intelectual, de feeling que un proceso mecánico, acá otro problema en el manejo de las empresas de software donde para hacer una tarea se piden tiempos fijos, escritos en piedra y firmados con sangre y que la gente administrativa, los vendedores, los directores no entienden y no ven como es posible que esas fechas nunca se cumplan teniendo que jugar con el triángulo de alcance, calidad y recursos, hay una corriente dentro del desarrollo de software que precisamente trata de atacar esto, que es no estimation.

Por último quiero mencionar otra idea interesante que se trata en el libro, que es que en términos de la meta, no necesariamente todos los recursos deben de estar produciendo todo el tiempo, de hecho esto es contraproducente... en términos de la meta, esto es, a veces (la mayoría de las veces) para llegar a la meta es muy recomendable que hayan recursos (materiales, maquinaria, equipo) y personas sin hacer nada, holgazaneando, echando la hueva, yendo a fumar, viendo los partidos de la euro, etc. esto por qué? por que de no ser así se causa un sobre inventario o una sobre carga inmanejable en ciertas secciones; esto, de nuevo, es algo que los managers no entienden y es uno de los cambios culturales más difíciles de hacer, ya que estamos acostumbrados a siempre tener a la gente ocupada (aunque no sea beneficioso en términos de la meta), haciendo algo, por que?, pues por que les pago por 8 horas de trabajo y no quiero obtener menos que eso, a esto le llamamos horas nalga, es decir, lo importante es que estés sentado frente a tu escritorio, pero como lo dice el libro y el sentido común, esto no es lo mejor, ya que si no ayudas a la meta, no tiene caso que lo hagas, por lo que lo mejor es que las cosas que se hagan estén bien pensadas y hay que aprovecharlas al máximo en términos de la meta. Acá en desarrollo de software esto se acrecienta aún más por que no sólo es que a veces es necesario que la gente no produzca, sino que como ya comentamos antes, es una actividad más parecida al arte que a otra cosa y esto implica que se debe de tener un ambiente adecuado para que fluyan las ideas y que el estado de ánimo sea el mejor para poder logra este fin, esto es, si es necesario que vean un partido de la euro para que el estado de ánimo sea el adecuado... hay que poner el partido de la euro y permitirles que lo vean sin problemas, pero esto, de nuevo, es un cambio cultural en el manager muy difícil de tener.

Ahora sí, por último, me llamó la atención cómo fue que Alex y su equipo se ganaron a un cliente muy importante, ofreciéndole entregas en partes de su pedido, con lo que pudieron cumplirle al cliente, ganaron dinero, se ganaron al cliente y le ahorraron dinero al cliente en inventarios, si, así es, hicieron sprints y entregas continuas, tenían reuniones de mejoras continuas, se enfocaban en darle valor al cliente ¿les suena?, así es, era algo muy similar a ágil, por lo que en la industria también funciona ( de hecho también existe esa corriente como "lean manufacturing").

En verdad les recomiendo ese libro, vale mucho la pena, como novela, como proceso de producción (introduciendo la teoría de las restricciones) y para los que estamos dentro del desarrollo de software, como marco conceptual del desarrollo ágil.

PD: Anita, muchas gracias por prestarme el libro, espero que cuando leas management 3.0 te sigan haciendo clic las ideas de la meta.