miércoles, 10 de diciembre de 2014

Metodologías Agiles: Programación en pares

En la metodologías tradicionales los programadores estaban atados a una estación de trabajo y de manera individual (y posiblemente asilada) desarrollaban su trabajo en élla. Su forma de trabajo dependía del nivel de madurez de los procesos de su empresa, pudiera ser que el resultado final dependiera exclusivamente de sus capacidades, o que se guie por algún proceso controlado, para garantizar la calidad del software, finalmente el código puede pasar a otra persona que lo revisaría (si es que este paso se da), y entraría en una serie de pruebas, evidentemente fallaría ( porque nunca funciona a la primera), y se regresaría al codificador para corregir los elementos que fallaron. Incluso puede ser que no fallara como tal, simplemente no cumpliera con las necesidades y expectativa del cliente (por que le cliente nunca está satisfecho, hablaremos de eso en otra ocasión). Además es posible que el código a corregir / modificar no le llegue al mismo codificador, si no a otro, que va a tener que tomar su tiempo en comprender el código, la necesidad del cliente y en realizar la modificación, y después de esto… después de esto, ¡Vuelta a comenzar!

Algunas metodologías ágiles, proponen un enfoque diferente a la programación individual. Es la programación en pares, o programación en pareja, esto es, literalmente, dos programadores trabajando en una misma máquina.

Antes de continuar me gustaría precisar que ninguno gran sistema actual, puede ser obra de una sola persona, elija la metodología que elija, por lo menos en un tiempo prudente. Tener un equipo de trabajo integrado por personas capaces de colaborar entre sí para llegar a fines efectivos, es fundamental para la construcción de software exitoso, el cual que cada vez es mas demandante y interconectado.

Aclarado lo anterior, continuamos con la programación en parejas, dos personas, una maquina… A Primera vista parece que es una pérdida de recursos, hasta que te lo ves funcionando y quedas maravillado con los resultados, que son (entre otros), los siguientes:

  • Aunque la velocidad de codificación no llega a ser la suma de ambos codificadores trabajando por separado (dicen que es un 15% menor), la calidad aumenta enormemente, ¿Qué quiere decir eso?, que las veces que el software retorna al codificador (o codificadores) es mucho menor. Es decir hay una disminución real del tiempo en tarda en salir a producción un software.
  • Agregando al punto anterior, hay un mejor código, no solo porque cuatro ojos los revisen, sino por que dos personas han llegado a un acuerdo consciente sobre qué es lo mejor.
  • Ambos codificadores se motivan entre sí, los dos están trabajando por un objetivo común, con lo que cada uno es el soporte del otro, y se da una dinámica de superación entre sí.
  • Homologación de conocimiento, cada uno transfiere sus conocimiento al otro, y es reforzado en su puntos débiles, si ambos desconocen un tema se apoyan para capacitarse.
  • Hay menos distracciones, lo normal es que los dos estén trabajando y no paren la ejecución del flujo de trabajo por cualquier cosa, incluso al verlos juntos las gente los molesta menos (aun así no es bueno olvidar hacer pequeñas pausas cuando sea prudente).
  • Se adquiere un espíritu de equipo real, que ayuda a la moral del mismo, se entiende que el problema de uno es problema del otro, y que ambos están trabajando para un objetivo común. Ya no tienen sentido los lobos solitarios de la codificación, cuyo código ni siquiera entienden ellos pasados unos meses.
  • Se favorece la comunicación. Los problemas, malentendidos y necesidades quedan inmediatamente resueltos, y no al día siguiente o hasta la próxima reunión.


¿Qué necesita una oficina para que funcione la programación en pares?

  • Escritorios juntos y amplios, se necesita estar cómodo, no se puede estar apretados e incómodos, hace falta espacio.
  • Dos monitores, una CPU, siempre debe hacer dos monitores por CPU, (y esto se entiende cuando se vive).
  • Posibilidad de hacer ruido. Lo codificadores necesitan, y estarán todo el rato hablando entre ellos.


Algunos detalles más para tener éxito:

  • La persona que no está en el teclado actualmente, es la que dirige la programación, menciona sus ideas en voz alta y el que está en el teclado las intenta plasmar en código, y aportar sus propias ideas, al cabo de una o unas pocas funcionalidad, cambian los roles.
  • Debe minimizarse la utilización de teléfonos móviles. El peor escenario posible, es que este codificando la persona del teclado y el otro este distraída en el teléfono móvil. Como comentamos la persona que no tiene el teclado, debe estar dirigiendo la programación.


Una vez que superemos los primeros recelos sobre la programación en parejas, y que consigamos armas equipos de programadores entusiastas y deseosos de mejorar, podernos aumentar nuestra producción y disminuir con creces nuestro numero de errores y fallos.

sábado, 29 de noviembre de 2014

Herramientas Imprescindibles: Control de versiones

Durante la semana un codificador me estaba exponiendo una excelente idea para poder resolver un problema, en mitad de la conversación que pregunta, "¿Crees que va a funcionar?" y le conteste: "No, nunca funciona a la primera" (Regla N°2 de la Ingeniera de Software: "Va a fallar").

Cualquier cosa o idea que tengamos nunca va a funcionar a la primera, y si funciona es que porque algo hemos hecho mal o estamos obviando algo. Las buenas ideas necesitan fallos para poder triunfar, montarle piezas y quitárselas hasta que se obtengan la forma ideal, y generalmente se necesitan más de una persona para hacer grandes proyectos realidad.

Ante tal panorama es importante el control, algo que nos responda rápidamente a las preguntas "¿Qué hice y donde lo hice?" y "¿Qué hicieron otros y donde?", a la vez que permitirnos regresarnos rápidamente sobre nuestro pasos, para poder emprender otra dirección más exitosa.

Este control nos lo permite las herramientas de "Control de versiones", que son medios automatizados para gestionar el código fuente, a través de su evolución. No solo eso, es como una máquina del tiempo (o mejor como una Tardis), que nos permite ver que ocurrió con nuestro código fuente (Porque todo cambia, Regla N°1 de la Ingeniera de Software: "Va a cambiar") , en una fecha determinada, quien hizo los cambios, y comprender el porqué. (por que todo tiene un motivo, Regla N° 4: Todo sistema tiene un propósito).

Pero, exactamente ¿Que debe permitir una herramienta de Control de versiones?

  • Gestionar los cambios que se hagan con nuestro código fuente, de una forma sencilla.
  • Integrar los cambios que hagan otros codificadores de forma automática.
  • permitirnos revisar dichos cambios a través del tiempo.
  • Permitirnos reversar cambios específicos de nuestro código ( es decir no se trata de reverso "todo o nada").
  • Debe funcionar de forma remota. Los programadores trabajan en sus maquinas (Cada uno en sus maquinas), y mediante el software de control de versiones, se integra todo en un repositorio que está en un servidor, de forma automáticamente. las cambios de los otros codificadores se integran a nuestro código (en nuestra maquina) de forma automática de igual modo.
  • Realizar ramificaciones de nuestro código.


El tema de las ramificaciones (branch) en un tema muy importante, que se explica con el siguiente ejemplo: Imaginemos que tenemos un determinado proyecto, del cual vamos a sacar la versión 2.0, con lo que usamos el control de versiones para gestionar nuestros cambios desde la versión 1.0 a la versión 2.0. La construcción dura unos 6 meses en cuestión de tiempo, pero a su vez tenemos la versión 1.0 la cual sigue siendo usada por nuestro clientes (porque seis meses es mucho tiempo), Esta versión tiene errores que necesitan ser corregidos o mejoras que no pueden esperar a la versiones 2.0. Aquí tenemos varias opciones:

  • No hacer nada para la versión 1.0, con lo que estaremos perdiendo seis meses de oportunidades de negocio.
  • Hacer los cambios en la versión 1.0 y cuando salga la versiones 2.0 incorporarlos manualmente, con la extremadamente posibilidad de perder código, o funcionalidad al hacer una mala "recodificación" de los cambios de la versión 1.0 a la 2.0.


La tercera opciones es hacer una rama de software con nuestra herramienta de control de versiones, esto seria así: Originalmente existe un solo proyecto llamado "Proyecto 1.0", que se ramificaría en dos. uno llamado "Proyecto 2.0" y otro "Proyecto 1.1 " (por poner un nombre), cada una con una serie de codificaciones independientes (y puede que un equipo de trabajo también). Llegado el momento la herramienta de control de versiones nos permitirá replicar (de forma automática), todos los cambios realizados desde la versión "Proyecto 1.0" hasta la versión "Proyecto 1.1", pero dentro del código fuente del "Proyecto 2.0". La integración del código será automática, y en el caso que existiera conflictos, se nos indicara para que los corrijamos manualmente.

Como comentamos, cada codificador trabaja de forma independiente en su máquina, y preferiblemente, hace una entrega de código (llamada frecuentemente commit) y una integración (automática) del código fuente de otros codificadores (llamada también frecuentemente update), todo esto pasando por un servidor remoto que contiene toda la historia del código fuente.

Pero existe otra forma de trabajar, mediante repositorios distribuidos, esto es un escenario en que cada codificador tiene una copia del repositorio en su máquina, y puede trabajar libremente con el sin aceptar a otros codificadores (puede hacer commit, revertir, crear rama e integrarlas, etc.). cuando el codificador lo considere oportuno puede integrar el código al repositorio común, para que este a disponibilidad de otros codificadores, al mismo tiempo que descarga el código de estos.

Aquí una pequeña guía para saber cuándo usar control de versiones en nuestros proyectos

  • Regla numero 1:¿Cuándo debo usar control de versiones?
Siempre.

  • Regla numero 2:Aun así, no sé si por el tamaño de mi proyecto debo usar control de versiones.
Ok, a veces es confuso, por favor en caso de duda revise la regla numero uno.

  • Regla numero 3:Pero no estoy compartiendo código fuente con otros codificadores, ¿Realmente es necesario usar control de versiones?
En este caso igualmente podemos aplicar la regla numero uno.


Por último Algunas herramientas de control de versiones:

  • Subversion:frecuentemente llamado SVN, uno de los más populares y más fácil de aprender, puede consultarse un excelente manual aquí, y descargase de aquí.
  • TorotiseSVN:cliente de SVN integrado con el explorador de Windows, una maravilla, puede descargase de aquí.
  • AnkhSVN:cliente SVN integrado con Visual Studio, se descarga de aquí.
  • VisualSVN Server:Un servidor de SVN, extremadamente sencillo de configurar, vale mucho la pena, incluso su licencia gratuita, de descargar de aquí.
  • Git:Control de versiones distribuido muy útil, quizás el mejor, algo difícil al principio, pero sin duda vale la pena el esfuerzo, se puede consultar el siguiente manual aquí, y descargarse el Gitde aquí.
  • TortoiseGIT:El homologo de TortoiseSVN para GIT, se descarga de aquí.


Aunque SVN es una excelente herramienta, mi recomendación es comenzar con GIT, aunque sea un poco más difícil, porque es sistema posterior que se creó con la intención de mejorar la debilidades de SVN. No obstante los creadores de Git, sabiendo de la gran difusión de SVN, crearon una capa de compatibilidad entre ambos sistemas, pudiendo trabajar con un cliente GIT en nuestra maquina (con toda sus ventajas) y un servidor SVN del lado remoto.

Por último una serie de reglas a aplicar en el uso de control de versiones:

  • Nunca subas al control de versión algo que no compila, solo te causaras el desprecio del resto de codificadores
  • Revisa línea por liana lo que modificaste antes de subirlo, si no reconoces un cambio reviértelo, debes reconoce todo lo que estas subiendo. Para realizar esta tarea el control de versiones tiene herramientas que te muestran que se modifico exactamente, de forma rápida y sencilla.Nunca te saltes este paso.
  • Haz update y commit tantas veces como sea posible (por lo menos una vez al día), si no tu versión del código de alejara de la versión de otros codificadores, y cuando quieres integrarla, te encontraras con un monto de conflictos.

domingo, 2 de noviembre de 2014

Estándares de programación: Preferiblemente usa bucles "foreach"

En cualquier lenguaje de programación hay una serie de estructuras básicas para realizar un bucle, en esta publicación analizaremos el bucle for y el bucle foreach, y la conveniencia de usar el segundo sobre el primero, el código mostrado sera en C# (aunque debiera ser semejante en cualquier otro lenguaje).

Comencemos viendo los tipos de bucle mas comunes:
  • Esta el bucle while:
1
2
3
4
while (SeCumplaCondicion())
{
}
while (SeCumplaCondicion())
{

}
Es el más básico, y se ejecutaría hasta que algo hiciera que se cumpla la condición.
  • bucle while tipo dos:

1
2
3
do {
} while (SeCumplaCondicion())
do {

} while (SeCumplaCondicion())
Garantiza que por lo menos se realiza una iteración del bucle antes de comprobar si se cumple la sentencia, por lo demás es igual que el anterior
  • El bucle for:


1
2
3
4
for (int i = 0; i < 10; i++)
{
}
for (int i = 0; i < 10; i++)
{

}
Este bucle se usa para recorrer algún tipo de array, o una colección, teniendo esta estructura

1
2
3
4
5
6
List<string> nombres = new List<string>() { "JUAN", "PEDRO", "ANA", "INES" };
for (int i = 0; i < nombres.Count; i++)
{
    Console.WriteLine(" Nombre :" + nombres[i]);
}
List<string> nombres = new List<string>() { "JUAN", "PEDRO", "ANA", "INES" };

for (int i = 0; i < nombres.Count; i++)
{
    Console.WriteLine(" Nombre :" + nombres[i]);
}
El resultado será algo parecido a:


  • Nombre :JUAN
  • Nombre :PEDRO
  • Nombre :ANA
  • Nombre :INES

Este bucle tiene varios problemas asociados:

lo primero es que usamos un numero para acceder a la colección, si nos fijamos nuestra intención no es trabajar con la posición de los nombres dentro del objeto, es decir nos da igual si es la primera o la ultima, nosotros queremos recórrelos todos en secuencia uno a uno. Su posición para nosotros es irrelevante. Esto es importante, por que se pierde el verdadero objetivo del código, hacer algo con todos los elementos del array, al margen de su posición. Requiera además que ya se sepan todos los nombres (los elementos de la colección) antes de procesar el bucle, en algunos casos no requeríamos conocer todo el escenario antes de querer procesarlo, por ejemplo, si estamos buscando un archivo en todo el disco duro, no sería recomendable que primero listemos todos los archivos y luego lo recorriéramos buscando el archivo idóneo.

  • El último bucle, es el bucle foreach, tiene la siguiente estructura


List<string> nombres = GenerarListaNombres();

1
2
3
4
5
6
List<string> nombres = GenerarListaNombres();
foreach (string nombre in nombres)
{
    Console.WriteLine(" Nombre :" + nombre);
}
List<string> nombres = GenerarListaNombres();

foreach (string nombre in nombres)
{
    Console.WriteLine(" Nombre :" + nombre);
}
En esta forma de bucle, se elimina el uso de los índices (int i), lo que simplifica su código y nos permite centrarnos en el objetivo real, que es recorrer los elementos de la lista.

El hecho de que el código sea más sencillo, lo hace a su vez mas mantenibles y escalable en un futuro.

Por otro lado el único requisito es que el elemento a recorrer implemente la interfaz IEnumerable, lo cual nos permite realizar ajustes a como se procesan los elementos, en este ejemplo se recorren los nombres hasta que se encuentra la palabra "PEDRO"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void Ejemplo2()
{
    foreach (string nombre in GenerarListaNombresEnumerable())
    {
        Console.WriteLine(" Nombre :" + nombre);
        if (nombre == "PEDRO") break;
    }
}
public static IEnumerable<string> GenerarListaNombresEnumerable()
{
    yield return "JUAN";
    yield return "PEDRO";
    yield return "ANA";
    yield return "INES";
}
public static void Ejemplo2()
{
    foreach (string nombre in GenerarListaNombresEnumerable())
    {
        Console.WriteLine(" Nombre :" + nombre);
        if (nombre == "PEDRO") break;
    }
}

public static IEnumerable<string> GenerarListaNombresEnumerable()
{
    yield return "JUAN";
    yield return "PEDRO";
    yield return "ANA";
    yield return "INES";
}
Esta función especial que devuelve los campos con la palabra yield, nos permite genera la lista de nombres al mismo tiempo que se está procesando, la ventaja es que no se generan nombres que no se van a usar (por ejemplo no se genera "ANA", ni "INES", en caso que poníamos anteriormente, si estuviéramos buscando un archivo por todo el disco duro, podríamos detener la búsqueda cuando encontráramos el archivos requerido, y no tendríamos primero que localizar todo los archivos y ver si cumplen las características que deseamos uno a uno.

Adicionalmente el listado de nombre no se puede modificar dentro de un bucle foreach, con lo que garantiza seguridad de no alteración del listado (los objetos dentro del listado si se puede mejorar).

Resumiendo las ventajas del bucle foreach, quedarían las siguiente:

  • Código más limpio y sencillo, que expresa mejor las intenciones del codificador.
  • No es necesario generar completamente los elementos a recorrer, antes de comenzar a recorrerlos.
  • No es posible modificar el listado original.


¿Cuándo usar un bucle for o una foreach?, en principio la mejor opción es siempre el bucle foreach, por los motivos establecidos, (sobre todo el de claridad en el código), salvo en el caso que realmente sea relevante la posición del elemento en la lista.

jueves, 16 de octubre de 2014

Regla N° 6: Lo importante es el "Que hace" y no el "Como lo hace"

Tradicionalmente cuando uno estudia programación por primera vez, en la carrera de Informática o afines, por algún motivo desconocido para mi, se comienza estudiando programación estructurada, a veces en pseudocódigo, en Pascal, en C, o quizás en Java, pero orientado de alguna forma estructura. Se ven bonitos diagramas de flujo (Flowchart), donde todo tiene un orden y una secuencia determina. Nos enseñan que un algoritmo es un proceso, pasó a paso, que con una misma entrada, produce una misma salida. Datos entran y datos salen.

Y después cuando ya está adaptado nuestro celebro para hacer las cosas de una determinada manera, ¡Bang!, nos cambian el paradigma a una la programación orientada a objetos, que curiosamente es el paradigma de programación que ofrece mayores virtudes en el desarrollo de software, es mas casi todos los lenguajes modernos de programación vienen con la coletilla "Todo es un objeto", frase que aunque ciertamente relativa, nos hace ver la importancia de este paradigma.

Pero ¡Ay!, todo se ve con el prisma de programación estructurada, incluso se aprende la programación orientada a objetos desde este enfoque, haciendo comparaciones, diferencia y similitudes. Todo esto hace que el aprendizaje este condicionado y limitado por un enfoque previo.

Hagamos un paréntesis en este punto para contar una pequeña anécdota. Hace años, tuve un maestro de historia, que nos comento el gran avance industrial que supuso la creación telar mecánico, que simplifica y automatizaba la creación de tejidos de distintas formas y colores, con lo que se vio una mejora en los tiempos en la fabricación, y una rebaja en su costo. Era como el principio de la industrialización, en la que mejores procesos, y avances se iba incorporando en la vida diaria de la producción de nuevos elementos, desde las mencionadas telas, a la fabricación de coches, hasta la llegada de microprocesadores y computadoras. También nos señalo que seria ridículo, que si exigiera un país en vías de industrialización, comenzara por los telares y continuara implantado poco a poco todos los avances tecnológicos de otros países, como queriendo recorrer su mismo camino, porque este jamás alcanzaría un mismo estatus industrializado (llego tarde a la carrera). La única solución posible seria que comenzara en el mismo punto tecnológico que corresponde a la actualidad, para que ambos pudieran progresar a la par.

Lo mismo pasaría con lo programación, que se quiere enseñar aparentemente en el mismo orden en que evoluciono esta disciplina, (Curiosamente cuando estudie sistemas, nos enseñaron, en este orden, los siguientes lenguajes de programación: Pascal, Fortran, C, Prolog, ADA, C++, Visual Basic 6 y Java, que básicamente fue el orden en que fueron creados, salvo los dos primero).

El problema del enfoque de la programación estructurada es que se enfoque demasiado en la forma de trabaja que tiene las computadores, esto es "Lo importante es como lo hace", ejecutando una por una las líneas de programación de un sistema, y realizando saltos en el flujo según determinadas instrucciones.

Los "humanos", no resolvernos problemas de esta manera, o por lo menos no generalmente, nosotros descomponemos un problema en elementos mas pequeños, a los que podemos catalogar, y les atribuimos características y propiedades, olvidando además aquellas datos y circunstancia que no su útiles para el problema, después generalizamos dichos elementos para que nos sirva en solucionar otra problemas parecidos. Este forma de pensamiento es donde prima "Lo importa es lo que hace", y es uno de los pilares de la programación orientada a Objetos.

En la programación orientada a objetos, se diseñan elementos, donde prima la representación de "Que es lo que hace" y "Que son", principalmente, a través de sus atributos y sus métodos. también se establece como se relacionan con otros tipos de elementos (o clases), ya sea mediante técnicas como la composición, la herencia, o el envió y recepción de mensajes.

De esta forma centrándonos en "Que hace" obtenemos una comprensión mas clara del sistema, y de sus requisitos, además construiremos un sistemas más escalable (debido a que no nos estamos centrando en "Como lo hace"). Inclusive tendremos muchas más posibilidades de conectarnos a otros sistemas, puesto que queda mas claramente establecidos los limites y conectores de estos.

Cuando nos centramos al contrario en "Como lo hace", obtenemos, entre otros, los siguientes problemas:

  • Un código lleno de sentencias if, y totalmente ausente de herencia y polimorfismo (la herencia se sustituye con bloques if, que se repiten en cada función).
  • Igualmente total falta de Interfaces, que son la máxima expresión del pensamiento "Lo importante es lo que Hace".
  • Un código lleno de clases estáticas, con simples métodos expuestos.
  • Funciones que en lugar de recibir objetos y trabajar con ellos, recibe una lista indeterminada de parámetros, con tendencia a crecer, uno detrás del otro y con ausencia de sobrecargas.
  • Separación de los datos y el negocio del sistema (en la programación orientada a objetos los datos (atributos) y el negocio son indivisibles).
  • Clases muy grandes cuyos métodos no tiene ninguna relación.
  • Clases muy pequeñas, porque no se tiene claro dónde colocar los métodos, y se crean nuevas clases para albergar pocos métodos.
  • Métodos desproporcionados (tanto por grandes, como por pequeños), con excesiva dependencia entre ellos.


Y lo más importante dificultad para modificar y comprender el código.

viernes, 10 de octubre de 2014

Claves del la Calidad: El equilibrio

Una de las claves de la calidad de un sistema, es el equilibrio entre tres factores principales: Tiempo, Recursos y Alcance. Juntos forman una especie de taburete de tres patas, sobre el cual esta nuestro desarrollo y donde si una de ellas esta desproporcionada, puede llevarnos al fracaso en la construcción de nuestro software.

El tiempo

El tiempo posiblemente sea el factor más difícil de manejar, es más, el tiempo en el desarrollo de software se curva en contra de toda ley de la física, y así dos meses se pueden convertir en seis y seis meses de trabajo deben caben en dos.

Es más posible que te toque la lotería, el día de tu cumpleaños, un 29 de febrero, sin comprar boleto, a estimar correctamente un proyecto.

Este factor hace referencia al espacio de tiempo que tenemos disponible para sacar un producto al mercado en el momento oportuno para que nos genere beneficios. Por ejemplo, el tema de la facturación electrónica en México, hace años era un bien escaso y la gente que le entro pronto a este mercado tuvo bastante éxito, pero en estos momento el mercado está saturado de proveedores de factura electrónica, y con una dura competencia, con lo que sería bastante difícil entrarle de cero a vender un nuevo producto de facturación.

Debido a que lo importante, como decimos es llegar en el momento justo, generalmente tiempo es el factor que más escasea.


  • Cuando tenemos poco tiempo

Se da generalmente un uso excesivo de los recursos, esto es, los involucrados en el sistema se ven obligados a hacer horas extras (con lo que se fabrica tiempo, se convertirán jornadas de 8 horas en jornadas de 10, 12 o más horas, aquí es donde caben seis meses de trabajo en dos), lo que principalmente provoca desanimo, cansancio en el equipo y software de baja calidad con multitud de errores.


  • Cuando tenemos demasiado tiempo

Se pierde el objetivo del sistema, y el interés en el mismo, igualmente el equipo se acaba sintiendo alejado del mismo proyecto (incluyendo al cliente), al no ver una producción real de su trabajo, y la meta queda diluida. Se baja la calidad del sistema al no tener un resultado real y tangible. Igualmente puede ser que el producto pierda su significado al no haber salido en el tiempo adecuado


  • ¿Cuál es la medida correcta?

Va ligado con el alcance, hay que tener tiempo reducidos en los que se desarrolle una iteración (entrega) que le haga sentido al cliente (o usuario), pero que sea los suficiente amplio para no caer en las horas extras innecesarias.

La primera entrega siempre debe ser la más larga, porque si bien no incluye toda la funcionalidad, es necesario que ya está sostenida sobre una arquitectura firme y concisa para todo el proyecto (sobre todo por se va a aplicar la regla "Va a cambiar", y si no se tiene en cuanta nos afectara a posterior).

Los recursos

En los recursos, se hace referencia a elementos tales como maquinas de cómputo, licencia de software, equipos especiales, dinero, y también a las personas "recursos humamos".


  • Cuando tenemos pocos recursos

Si tenemos pocos recursos "físicos", como equipos hardware (o elementos de software que se deben compartir como bases de datos), puede ser que los participantes del proyecto compitan por ellos, con lo que más que un elemento de cooperación se convierte en uno de contienda, generando roces y malestar en general.

Si se tiene menos personas de las necesarias, se produce una sobrecarga de trabajo de dichas personas, es decir, hacen horas extras. Al final por el cansancio es normal tener descuidos y fallos, y estos a su vez provocan retrabajos, (y más horas extras).

Si no se aplicaran horas extras, no queda de otra que reducir el alcance (si un es una "pata" es otra).


  • Cuando tenemos demasiados recursos

Que al final tenemos recursos que no hacen nada, y por lo tanto tenemos perdidas de dinero (o lo gastamos innecesariamente)

¿Puede llegar un punto donde haya demasiados recursos? Si, generalmente hay personas claves en los proyectos (como los lideres), que no pueden gestionar apropiadamente un número determinado de recursos o personas si este es excesivo, con lo que se provoca un descontrol en la gestión del proyecto , o se crean estructuras jerárquicas (en forma de árbol), en las que se depende de otras persona, que delegan trabajo a su vez en otras, al final se pierde facilidades de comunicación, y se generan mecanismos demasiado burocráticos para controlar el proyecto (lo que influye principalmente en el tiempo y en conocer realmente las necesidades del cliente).


  • ¿Cuál es la medida exacta?

Lo recursos para un proyecto deben llegar en el momento adecuado, si llegan demasiado pronto, es posible que estén en desuso y si llegan demasiado tarde, es posible que lleguen a ser inútiles (o que el proyecto ya se haya cancelado por falta de estos). Los recursos deben llegar en el momento que puedan ser usados, y liberarse cuando ya no son necesarios.

El alcance

El alcance representa la cantidad de funcionalidad que se va a liberar.


  • Cuando nuestro alcance es demasiado pequeño

Generalmente el sistema no sirve para aquello que el cliente quiera que sirva. Este nunca estará satisfecho con el sistema y le generada una sensación de descontento (Por no hacer el sistema lo que él quiere que haga).


  • Cuando nuestro alcance es demasiado grande

Cuando esto ocurre generalmente se crea una proyecto inacabable, en el que ni el cliente, ni el equipo de desarrollo ven un producto tangible, y es muy probablemente que se abandone el proyecto.


  • ¿Cuál es la medida exacta?

Entregas continúas de corto alcance, en el que se libere una funcionalidad nueva en cada iteración, de forma que los retos y las metas sean alcanzables a la vez que interesantes para todos los implicados en el desarrollo del sistema.

sábado, 4 de octubre de 2014

¿Qué es la calidad?

La palabra "calidad" tiene muchas definiciones y criterios según el ámbito o la persona que este proporcionando dicha definiciones.

Según la rae calidad es "Propiedad o conjunto de propiedades inherentes a algo, que permiten juzgar su valor", otras definiciones son por ejemplo "Es la aptitud de un producto o servicio para satisfacer las necesidades del usuario.".

A lo largo de mi carrera he recibido diferente opiniones sobre que es la calidad, con mayor o menor atino, me quede con la que recibí cuando desempeñaba labores de tester, al inicio de mi vida profesional.

Estaba en mi primer trabajo, en el que mi labor era realizar pruebas de diversos tipos sobre el portal Web de la empresa (era un servicio de búsqueda), hacíamos pruebas de stress, de volumen, o de carga entre otros tipos de pruebas. en mis primeras semanas de capacitación, el líder del equipo de pruebas me pregunto, "¿Cuántas peticiones web debiera poder soportar el sistema?", "Todas" conteste yo, a lo que él me volvió a preguntar, "Es decir si tenemos 100 peticiones en un minuto, debemos responderlas todas, y si tenemos 2000 en un minuto también ¿no?, y ¿si tenemos un millón en un minuto, también verdad?", a lo que yo contestaba que si, a todo, cada vez menos convencido de mi mismo, "Ok", prosiguió, "y si solo recibimos de media 100 peticiones al minuto y si la infraestructura para contestar ese millón de peticiones sea demasiado costosa para nosotros y no se podría amortizar, ¿debiéramos seguir respondiendo ese millón de peticiones?", y allí se plateo la primera duda sobre la calidad, el responder unas 100 peticiones al minuto, parecía suficiente, debido al tráfico que tenia la pagina actualmente, pero si se llegara a un irreal caso de un millón de peticiones al minuto, el sistema no podría responderlo. entonces ¿Era buena o no la infraestructura sobre la cual estaba el sistema?. Aquí descubrí una nueva definición de calidad relacionada con el ámbito real de trabajo.

La calidad es una medida de aceptación, por la cual se contrapone los fallos de los sistemas, con respecto a su aciertos, y en base a dicha relación se decide sobre la viabilidad de un producto. Por ejemplo nuestro sistema permitía contestar apropiadamente 500 peticiones en un minuto (mas que las 100 que recibíamos realmente), a partir de las cuales comenzaba a tardase en responder al cliente. Esto nos daba un posible punto de control y un enfoque sobre cómo y por qué tenemos que tomar medidas de recuperación y prevención.

Una vez identificada la calidad del sistema, (por ejemplo un marguen o limite de respuesta de 100% en menos de 500 peticiones en minuto, y descendiendo a partir de allí), hemos establecido los márgenes reales sobre los que puede operar este y en base a esa "medida" de calidad, podemos establecer si aceptamos el sistema o no (es decir si el sistema satisface nuestras necesidades)

Me gusta este enfoque particularmente por qué parte de la regla "Va a fallar" y en base a esa establece en que términos fallaría, y como lo haría, lo cual no da un posible escenario de trabajo y estar listos en cuando un comportamiento anómalo del sistema, a la vez que desarrollar un plan de contingencia adecuado. Dicho de otra manera enfoca la calidad en descubrir sus deficiencias, y no en ensalzar sus virtudes.

domingo, 28 de septiembre de 2014

Regla N°5 de la Ingeniería de Software: No te repitas

"He redactado esta carta más extensa de lo usual porque carezco de tiempo para escribirla más breve.", Pascal

Aunque pareciera que la frase anterior, perteneciente a Pascal (el matemático, no el lenguaje de programación), no tuviera que ver con el tema "No te repitas", quise mencionarla porque igual que dicho tema, representa la idea de que hacer las cosas bien lleva tiempo, y que un aparente volumen superior de "líneas" no representan más trabajo, ni más esfuerzo, sino un conjunto de datos innecesarios (o repetidos) que restan valor al resultado de nuestro trabajo. Por ejemplo la pregunta correcta no sería ¿que pesa más un kilo de paja o un kilo de plomo?, sino ¿que es mas manejable un kilo de paja o un kilo de plomo?

La regla "No te repitas", hace referencia a que no se deben repetir porciones de código, con funcionalidades iguales, "casi iguales", o parecidas a los largo del código. Aunque técnicamente funcione y de el resultado correcto, aumenta el grado de "degeneración del software" (el tiempo en que se echa a perder un software, hasta que ya no es útil su funcionalidad).

Recuerdo una vez en que me toco auditar un sistema auxiliar en que se tenía que hacer una serie de sencillas copias desde una fuente de información a otra, aplicándole una serie de transformaciones. Las fuentes eran diversas y los destinos también, en este caso se cayó en el ejemplo de "casi se parece", mas sin embargo, si se elijo hacer un proceso completamente independiente para cada fuente de información, pensando en la sencillez de hacerlo así, por la rapidez y por resultar así más cómodo. Inevitablemente se aplico la regla "Va a cambiar" y la regla "Va a fallar". A lo largo del proyecto cambiaron en multitud de ocasiones el formato y las características de las fuentes de datos de los orígenes y de los destinos, teniendo que modificar una y otra vez todo el código fuente y replicando ese código a cada uno de los escenarios "que casi se parecían". Evidentemente todo esto se pudiera haber evitado con una correcta programación orientada a objetos, donde el código "casi igual" se hubiera abstraído para convertirse en la clase base, y las particularidades de cada fuente en clases heredadas.

En el caso anterior solo es un ejemplo sobre como querer hacer algo rápido, acaba convirtiéndose en retrabajos innecesarios e inevitables horas extras.

Un sistema lleno de código repetido, oculta un diseño pobre del sistema, que evidentemente tenderán a "salir a flote" en el peor momento posible.

Algunos motivos de un código repetido son:

  • Como mencionaba, un pobre diseño de la solución a resolver (precedido posiblemente por un pobre análisis).
  • Un equipo poco integrado y con poca comunicación. Me ha tocado ver que cada integrante de un equipo de construcción, creara exactamente una misma funcionalidad, pero cada uno implementándola de una manera diferente según sus necesidades y criterios.
  • Una arquitectura deficiente, que obliga una y otra vez a repetir lo mismo.
  • Programadores que quieren tomar atajos, o lo que es lo mismo "pan para hoy y hambre para mañana" (y generalmente "mañana", es el día siguiente, literalmente).
  • Falta de comprensión de la programación orientada a objetos: Esta es más frecuente de lo que se pudiera pensar, si bien muchos codificadores tiene claras las bases de la programación orientada a objetos, les difícil situar dichas bases en un contexto practico y real.
  • Miedo a tomar el código existente por si llegara a dejar de funcionar: unos tres programadores "miedosos" encadenados y el código será imposible de comprender...

Para evitar tener código repetido, algunas recomendaciones serian las siguientes:

  • Tener el principio de abstracción siempre en la mente, buscar siempre lo abstracto y común de cada problema, y paramétrizar (o heredar más bien) las particularidades de cada solución
  • Conocer los patrones de software, y buscar soluciones de que nos permitan reutilizar código (o más bien objetos) en ellos.
  • Equipos integrados con buena comunicación, que compartan una serie estándares.
  • Refactoring para eliminar las partes de código repetidas.

domingo, 21 de septiembre de 2014

Regla N°4 de la Ingeniería de Software: Todo sistema tiene un propósito.

Olvidar el propósito de un sistema, es condenarlo al fracaso.

Hace bastantes años unos de mis primeros acercamientos al mundo de sus sistemas fue cuando estaba probando un sistema de PC que permitía dos personas compartir información (casi siempre texto), a través de un módem de 3200 baudios conectado a un puerto COM y a la línea telefónica convencional. No era a través de Internet (que no era ni barata ni común en aquel entonces), sino directamente con un módem llamando a otro módem, a través de un numero de teléfono convencional. Una vez, establecida la conexión, ambos usuarios se les permita intercambia frases y pequeños datos a través de esta con una velocidad extremadamente lenta. No era gran cosa, y sus posibilidades eran limitadas (tan limitadas que hubiera sido mejor una llamada telefónica normal), pero quede fascinado con el mecanismo que permitía a dos computadoras estaban unidas, a kilómetros de distancia, intercambiando bytes entre ellas. Cuando intente compartir con entusiasmo mi entusiasmo sobre la posibilidad en la que dos ordenadores podían intercambiar datos entre ellos, una persona me señalo que lo realmente impresionante, es que dos personas podían intercambiar datos entre ellas. Jamás se me ocurrió verlo así, para mí solo era un intercambio de bytes, cuando realmente representaba una comunicación e intercambio de información entre personas, objetivo real del software.

Esa fue una de las primeras lecciones de ingeniera de software que recibí. No podemos tener una visión puramente técnica de los sistemas y olvidar las necesidades operativas o de negocio para los cuales son realmente creados.

Es común que olvidemos que lo que estamos creando no es un conjunto de variables, y líneas de código, sino que tiene que un significado y relevancia especial fuera del lenguaje de programación en el que los estamos creando. Por ejemplo, una trasferencia bancaria de un millón de dólares errónea no es una posición de memoria mal inicializada, sino que puede ser una pérdida real, o un sistema médico de monitores mal construido puede poner en juego vidas humanas. Hay que pensar en nuestros sistemas por lo que van a poner aportar en un negocio o los problemas que van a poder resolver y no como simples entes tecnológicos.

En metodologías clásicas, en las que esta separado el programador del cliente, y se llega a construir el software por una serie de fases encadenadas claramente diferenciadas, en normal que el programador se centre en los aspectos tecnológicos de la solución olvidando el motivo de la solución misma. Esto crea sistemas técnicamente correctos, pero que sirven de poco, al no satisfacer las necesidades del cliente. En la nuevas metodologías agiles, se intenta que el cliente sea parte del equipo, con lo que es mas fácil comprender su punto de vista y aprovechar su conocimiento para crear un sistema funcional.

Es importante recordar que nuestro sistema es un ente que después va a ser usado por alguien, si nuestra sistema no se pueda usar más que en un ambiento de desarrollo y por nosotros mismos, no resuelve nada. Igualmente Hay que poner el propósito (la necesidad, el por qué se hacen las cosas) en primer lugar y usarlo como nuestro camino y nuestra guía para encontrar la solución.

martes, 16 de septiembre de 2014

El problema del martillo de oro.

Un martillo es una cosa maravillosa, es fácil de manejar, ergonómico, y transportable, maximiza mi eficiencia y minimiza mi esfuerzo. ¡No debiera tener problemas en cambiar esta rueda pinchada a martillazo!

Es frecuente que tengamos herramientas, tecnologías o lenguajes de programación, que parecen idóneos para resolver las necesidades de construcción de un software, a veces parecen incluso idóneos para resolver cualquier problema. Pero sin darnos cuenta habitualmente moldeamos nuestros requerimientos para que se ajusten a nuestra herramienta, y no estamos buscando herramientas que se ajustes a nuestros requerimientos, lo cual limita el alcance y las posibilidades de nuestra solución. Es necesario usar la herramienta adecuada, para resolver cada problema, no podemos quitar un tornillo a martillazos.

El ciclo de vida de estos "martillos" es generalmente el siguiente:

  1. Se propone usar el martillo, ya sea por una orden gerencial, estratégica, porque ya se compro o por decisión del programador.
  2. El algún momento se ensalza tanto el martillo, que se convierte en un estándar, y en la herramienta que todo el equipo (o la empresa), debe usar para resolver sus problemas.
  3. El "martillo" causa "desastres", como errores, mal código (o código poco comprensible), retrasos, y diversas frustraciones en el equipo (junto con horas extras y desencanto en los proyectos).
  4. Se desecha el martillo, bajándolo de su pedestal y se busca un nuevo martillo.

En todo este ciclo, posiblemente se desaprovecho una buena herramienta, usándola en circunstancia en donde no era idónea. Con lo que al final de su "ciclo", se explotaron todas sus desventajas y ninguna de sus ventajas.

Algunos martillos tradicionales son:

  • Todo debe estar en un procedimiento almacenado: Los procedimientos almacenados se convierte prácticamente en todo el sistema, y ellos tiene toda la lógica de nuestro negocio. Usando este martillo, tendremos un sistema difícil de mantener, cuyo diseño se base prácticamente en cómo se almacenan los datos (y no en lo que esos datos representan), y con limitaciones, como falta de programación orientada a objetos, que generalmente no ofrecen los gestores de base de datos, finalmente a ser la base de datos un elemento centralizado, se complica la implementación de un sistema por equipos, incluyendo el uso de herramientas de control de versiones.
  • Todo debe estar en un servicio: Se crea todo un sistema como una serie de llamadas a un servicio (puede ser un servicio web). Básicamente todas las funciones de nuestro sistema están imprentadas como métodos de un servicio, Se pierde el diseño de un software orientado a objetos, y generalmente se construye un software lento.
  • Todo debe ser accesible por un ORM: Toda las consultas a base de datos son a través de un ORM, no importa qué tipo de consulta, ni cuales sean las necesidades, generalmente caemos en este caso en software lento.
  • Construir el software en C (o C++) porque es rápido: Aquí habría que plantearse, primero, si es cierto eso sea tan rápido, y si dicha rapidez compensa en el uso de dichos lenguajes, cuya curva de aprendiza en mayor, y no cuidan mucho que no hagamos locuras al momento de usarlos (como por ejemplo Java y C#, donde se nos protege de usos indebidos de la memoria).
  • Programar en el blog de notas (o similares): Esto es querer hacerlo todo a mano perdiendo la cantidad de posibilidades que nos facilita IDE, como depuración, sintaxis coloreada, o IntelliSense.


La idea final es usar la herramienta adecuada en cada momento y necesidad, no casarnos con una sola tecnología, metodología o lenguaje de programación y poder de extraer lo mejor de cada una.

lunes, 15 de septiembre de 2014

Regla N°3 de la Ingeniería de Software: Se va a mantener

El tiempo que vas a estar creando software nuevo, es incomparablemente menor al tiempo que vas a estar manteniéndolo.

Gran parte nuestros esfuerzos de desarrollo van a estar enfocados en el mantenimiento de código que bien puede ser código ajeno o código de otras personas.

El peor escenario donde hay que mantener un software, es donde el código se ha ajustado durante años al gusto, y costumbres particulares de un analista-programador, que no ha seguido ninguna regla en concreto para creación del producto. Generalmente estos sistemas se vuelven contra su creador, convirtiéndose lo que debiera ser un aparente software sencillo, en vacaciones pasadas en la oficina en lugar de en la playa. La situación solo puede acabar de varias formas

  • Rehacer el sistema desde cero (con un nuevo programador).
  • No actualizar nunca el sistema, y por lo tanto limitar las posibilidades del negocio para el cual se aplica (hasta que se hace demasiado evidente que el sistema ya no sirve, y se cae en el primer punto).
  • Explotar al programador (horas extras, falta de vacaciones), hasta que este renuncie, y se vuelve a caer en el punto número uno.

A veces noto a ciertos programadores querer hacerse imprescindible para la continuidad de un sistema, mi consejo es que no caigan en ese juego. Al final se hacen esclavos del sistema, en lugar de hacer que el sistema les reporte beneficios. Lo ideal es que a un empleado le quieran por lo que es capaz de hacer en el futuro, y no que dependan de él por lo que ya ha hecho, debido a que generalmente las empresas buscaran cortar esa dependencia lo antes posible y de la manera más beneficiosa para la ellas y no para el empleado. Diferente es el caso en el que un empleado es requerido por sus conocimientos y capacidades ya que es una inversión a largo plazo. Resumiendo la idea seria "ser un buen programador tiene beneficios, aunque a veces no son tan visibles".

Volviendo a la idea del mantenimiento de software, nuevamente es una idea que debemos asumir como cierta, y para la cual debemos estar preparados, algunos consejos son:

  • No programes de forma artística: la programación no es un arte, eso no quiere decir que no sea creativa, ni importante, ni interesante, sino que generalmente es una creación "objetiva" a la que deben llegar un equipo de desarrollo en conjunto. Si lo vemos como un arte, lo veremos como algo muy personal (y subjetivo), que acabara siendo difícil de mantener.
  • Sigue estándares: antes de comenzar un desarrollo, es importante tener claro los estándares y que sean conocidos (y afectados) por todo el equipo de desarrolladores.
  • Haz un plan de manteniendo de un software, mas cuando este no tiene estándares o lógica aparente: Si te toca un software de este tipo, planea como vas a hacer las cosas a partir de ahora, donde podrás el acceso a datos, donde la seguridad, servicios globales, etc.
  • Intenta comprender el software desde el punto de vista de las personas que lo hicieron: Muchos proyectos reflejan el cansancio y la frustración desde las horas extras, al momento de su construcción. Para comprender el código piensa desde esa perspectiva, y ve donde esta los huecos de "lógica" y los posibles errores cometidos.
  • Haz refactoring siempre que puedas: El refactoring no es trabajar doble, es trabajar ahora para descansar mañana (y pasado mañana). Nunca subestimes el refactoring, no tengas miedo de mover algo que no entiendes, al contrario, buscar entender lo que estas moviendo (apóyate en el punto anterior).
  • Siempre utiliza control de versiones (el que sea, GIT, SVN,...). No hay proyecto demasiado pequeño para usar control de versiones, no importa que sea un proyecto individual o en equipo, siempre úsalo.

Finalizando, recuerda que el valor del software, está en su capacidad de ser mantenibles, dicho de otra manera, si un software no se puede mantener, perderá su valor muy rápido a través del tiempo, ya sean meses o escasos años (uno o dos). Las necesidades profesionales o empresariales del mundo cambian demasiado rápido, evolucionan siempre en nuevas necesidades, y cualquier necesidad requerirá de un software que la gestione. Esforzarse en crear un software mantenibles desde sus raíces, es una inversión en recursos y tiempo, que dará beneficios en un corto tiempo en la vida del sistema donde esta implementado.

sábado, 6 de septiembre de 2014

Regla N°2 de la Ingeniería de Software: Va a fallar

Si no falla es que no se usa…

Es imposible determinar si cierto software continuara funcionando en un futuro, porque las condiciones en las que se verá envuelto son impredecibles (actualizaciones de software con el que convive, actualizaciones de hardware… incluso la fecha y hora del ordenador). Si bien es cierto que podría decirse que la informática es determinista, el costo de determinar todas las opciones posibles, es demasiado alto.

Muchos de los primeros problemas que nos encontramos son al pasar de un ambiente de desarrollo, donde todo funciona, a otro ambiente de productivo donde parece que cada paso que damos en un problema a corregir.

Hay que evitar actitudes optimistas con respecto a la posibilidad que ocurran fallos, puesto que es muy probable que estos ocurran, por otro lado considerar que el usuario del sistema hará un uso “lógico” o coherente de este, es un desatino, generalmente nos sorprenderá descubriendo errores, que nunca se nos hubieran pasado por la cabeza.

Una vez más la visión correcta es aceptar que los fallos van a ocurrir e intentar establecer mecanismos para mitigar su impacto.

Algunos de estos mecanismos son:

  • Poseer un ambiente de pruebas, semejante al ambiente de producción, pero que no tengas ninguna afectación real en las operaciones, además de estar completamente aislado del ambiente de desarrollo.
  • Asegurar que tenemos trazabilidad de los errores (esto es que podamos reproducir el camino que se siguió para generar el error). Esta es una de las más difíciles y opacas, con lo que de antemano debemos prever esta situación y diseñar nuestro software para tal efecto.
  • Mantener el código sencillo, en base a estándares, que sea fácilmente comprensible por el equipo que está trabajando actualmente con el codigo (no solo por el que genero el código).
  • Usar herramientas de control de versiones. Frecuentemente una “pequeña” modificación de código genera “desastrosos” resultados en nuestras operaciones, es importante poder localizar fácilmente estos cambios.
  • Creación de pruebas unitarias, que nos ayuden a probar de forma automática y completa todos los elementos de un sistema (aunque sea por separado), evidentemente esto tiene que venir de la mano de una arquitectura, cuyo diseño nos permite probar el sistema de forma unitaria.

Un último consejo, “No repitas código”, a veces me he encontrado con inmensos bloques de código completamente iguales, salvo algún pequeño detalle. Es necesario estructurar correctamente nuestro software, y evitar la duplicidad del código (mediante funciones, herencia o patrones de software), porque basándonos en la regla “Va a fallar”, cuando más código igual tengamos en nuestras aplicaciones, mas tendremos que trabajar para repararlo (con la casi certeza que no lo vamos a corregir en todos los lados donde esta duplicado).

domingo, 31 de agosto de 2014

Regla N°1 de la Ingeniería de Software: Va a cambiar

En serio va a cambiar...

Esta debería ser la primera regla en cuanto al diseño de software, la regla sobre la que se debe sustentar todo el enfoque con respecto al análisis, el diseño y la codificación de un sistema software.

Todo cambia muy rápido en el proceso de desarrollo de un software, el mismo software construido, genera nuevos requisitos, la satisfacción de las necesidades de un proyecto, genera a su vez nuevas necesidades.

Explicado de otra forma la resolución de un problema, genera un entendimiento más claro de dicho problema, y en esta situación, se abren nuevas posibilidades sobre las capacidades del software y el negocio que sustenta.

Actualmente es muy difícil encontrar un proyecto que funcione con las fases tradicionales de la ingeniera de software, y que no requiera regresos continuos a las fases de análisis y diseño, además de un alargamiento innecesario de las fase de construcción. Ese el motivo del auge de la metodologías ágiles. Están pensadas desde un principio para ser validas en un contexto donde el cambio de los requisitos y las necesidades de los usuarios son constantes.

¿Significa esto que los cambios en mitad de la construcción de un software, es algo bueno y deseable?, no necesariamente, no es algo que se deba plantear en esos términos, más bien es algo que se debe aceptar como la realidad el día a día, y preparar nuestros procesos y enfoques para el cambios, si nos negamos a él, solo repercutirá en inacabables horas extras de construcción.

Desde un primer momento debemos estar listos y asumir que nuestro proyecto va a cambiar, y adaptarnos rápidamente a ese cambio, para lo cual necesitamos apoyarnos (entre otros) en los siguientes puntos:

  • Metodologías que estas diseñadas para gestionar los cambios.
  • Herramientas para gestionar los cambios en el software (como herramientas de control de versiones).
  • Herramientas para gestionar las necesidades y los requisitos.
  • Herramientas para probar el software de manera automatizada, para controlar el impacto del cambio en nuestro software de una manera rápida.
  • Software diseñado (y construido) desde el puntos de vista del cambio.
  • Software generado automáticamente, mediante técnicas de generación automática de código.
  • Equipos cuyos integrantes que compartan un "mismo lenguaje", esto es que entienda y apoyen un conjunto de prácticas y estándares de programación, y objetivos comunes para todos.

Profundizare en un futuro en cada uno de estos puntos.

lunes, 25 de agosto de 2014

¡Odio las horas extras!

¡Odio las horas extras!

Aunque es una verdad a medias...

Como muchos otros profesionales del ramo de la ingeniera del software y particularmente la programación, comencé desde muy joven en este mundo, fascinado por la magia de esta profesión, trasnochando para poder encontrar una solución a un problema que se resistía o a un nuevo desafío que me mantenía despierto. Era una sensación difícil de explicar.

Llegado el inicio de mi vida profesional, me vi embarcado en multitud de proyectos, en los que hacer horas extras era los más habitual, pero la sensación no era la misma, no estaba disfrutando lo que estaba haciendo. En cada problema que resolvía, me preguntaba cual era el motivo por el cual habíamos a este punto, y porque nos veíamos mas enfocados a resolver problemas (ya fueran por nuestra culpa o persistentes) que en desarrollar software, que era lo que realmente nos gustaba.. Pareciera que cuanto más esfuerzo y tiempo se dedicaba a un problema, mas problema surgían a su alrededor que requerían a su vez mas tiempo y esfuerzo.

Desde entonces tuve una inquietud creciente, sobre la inutilidad de dedicar tiempo y recursos a proyectos mal enfocados, en los que se desperdiciaban recursos y energías en tareas repetitivas y poco optimizadas. Empecé a interesarme por cualquier proceso que ayudara a aumentar la productividad y la calidad del software.

Los temas en los que más profundice (sin ningún orden en particular) son:

  • Creación de estándares de desarrollo empresariales.
  • Reutilización de código.
  • Creación de software sostenible.
  • Uso de herramientas que ayudan a la codificación
  • Patrones de software
  • Generación automática de código.
  • Automatización de procesos
  • Integración de equipos de desarrollo

El objetivo de este blog, es compartir mi experiencia para ayudar a minimizar al máximo las horas extras, y poder dedicar nuestro tiempo a lo que realmente nos gusta, o nos importa.

¡Allá vamos!