Showing posts with label Extreme Programming. Show all posts
Showing posts with label Extreme Programming. Show all posts

Monday, 19 October 2009

Tuesday, 21 July 2009

El principio PIE (Program Intently and Expressively)

Hoy quiero compartir con vosotros uno de los principios ágiles más importantes llamado PIE Principle (Program Intently and Expressively). Vendría a ser "programa atentamente y expresivamente". Hace tiempo que sigo los pasos de las buenas prácticas AGILE, y a mis colegas siempre les hablo de éstas practicas al igual que sobretodo utilizarlas. Sobretodo del DRY y del YAGNI que son muy importantes para mantener tu código limpio y entendible.


El principio PIE se basa en que el código debe ser más entendible, y que debemos evitar cosas como estas:


box := TBox.Create(1); //Direction = 1 - Down


Como podéis ver en el ejemplo, en la creación del objeto aparecen parámetros que a primera vista ni siquiera entendemos. Una codificación numérica expresa solo eso "números" y a lo mejor internamente si siguiésemos el programa veríamos que ese número significa un estado. Por lo tanto, la solución es simple, utiliza el estado en vez de un número, de esta manera estamos haciendo el código más entendible y simple.

Para solucionar el ejemplo anterior, solo tenemos que crear un tipo enumerado que cumpla con el significado de la creación de nuestro objeto:


type
TDirection = (isUp, isDown, isLeft, isRight);


begin
box := TBox.Create(TDirection.isDown);


Según el libro Practices of an Agile Developer, Andy hunt nos describe el PIE principle como:
Code you writemust clearly communicate your intent and must be expressive. By doing so, your code will be readable and understandable. Since your code is not confusing, you will also avoid some potential errors. Program Intently and Expressively.
Otro de los puntos fuertes es sobre el tema de los arrays o de los punteros con los índices +1/-1 los cuáles nunca sabemos si lo tenemos que incrementar o decrementar. Todos estos problemas hay que tenerlos muy en cuenta a la hora de ponerse a programar y evitar crear parxes para evitar estos problemas. En el libro también nos lo comentan:
Never kludge in a fix without understanding. The +1/-1 syndrome starts innocently enough but rapidly escalates into an opaque mess. Fix the problem, not the symptom.

Monday, 20 July 2009

Programación en Pareja (Pair Programming)

Muchas de mis conversaciones me han llevado a hablar sobre diversos axiomas o principios del Agile. Siempre intento seguir el DRY (Don't repeat yourself) y el YAGNI (You ain't gonna need it). Otro buen principio es el Pair Programming. En que consiste la programación en Pareja?, pues bien consiste en que 2 programadores combinas sus esfuerzos de desarrollo en un mismo sitio de trabajo. Por lo tanto, cada uno realiza una acción que otro no está haciendo: mientras uno codifica, el otro prueba unidades o piensa en ejemplos. La persona que pica el código es el "Driver" y el que revisa el código es el "Observer". Los 2 programadores deben intercambiar roles cada x tiempo. Diversos estudios demuestran que la programación en pareja es un 15% más lenta que la programación normal, pero que genera un 15% menos de errores.


  • Beneficios de la programación en pareja:
  1. Mejores Ideas - brainstorming continuo, conocimiento más amplio del problema y menos lagunas en la comprensión y mejores habilidades para resolver problemas de diseño.
  2. Mejor Calidad - menos errores, validación instantánea de ideas, enfoque coherente y una adhesión más estricta a las convenciones del equipo.
  3. Mejor Conocimiento - compartir experiencia y conocimiento, mayor entendimiento del porqué, cómo y que fue hecho.
  4. Incremento de la Productividad - mejor enfoque y mayor intensidad, impulsando y motivando a los demás para lograr mejores resultados y perder menos el tiempo.
  5. Mayor disfrute - a la mayoría de las personas les gusta trabajar en grupo y resolver conjuntamente problemas de interés..
  • Cuándo se vuelve efectivo?
Como podemos ver en el gráfico, el factor más importante es emparejar las habilidades y los retos. En la programación solitaria (Solo Programming) uno es más productivo en el modo de Flujo ya que sus habilidades y retos están igualados. El Pair programming crea un modo más eficaz, el Coaching en el que se aumenta la productividad global.

Conseguir el éxito:
  1. Modo Flujo - dos programadores trabajando en un difícil e interesante problema. Pueden tener diferentes habilidades y desafíos, pero ambos son capaces de encontrar una buena solución. Se puede obtener mediante el flujo de trabajo la resolución de una tarea compleja que combina su capital intelectual, conocimiento y experiencia para crear la mejor solución.
  2. Modo Coaching - Un programador experto con experiencia y conocimientos para resolver el problema los comparte con otros programadores que no puede resolver el problema por sí solo. Este programador junior tiene más fundamentos para entender la solución y aplicación. Se aprende y se crece para poder convertirse en un mejor programador.
Conseguir el fracaso:
  1. Desperdiciar el tiempo de los expertos - el problema es demasiado simple que hace que la participación de expertos sea ineficaz.
  2. Novato Abrumado - el problema es demasiado complejo o requiere de nuevos conocimientos que impiden que el programador aprenda algo útil.
En conclusión, el pair programming es una de las herramientas más útiles en el arsenal de un equipo de software. Ahora intenta saber cuándo y cómo utilizarlo.

  • Referencias de interés:
Pair Programming Illuminated.
Extreme programming and Agile methods.
Favourite Jokes.

Tuesday, 7 July 2009

Convertir ficheros ruby a ejecutables (exe)

Existe un wrapper que nos permite envolver nuestro script hecho en Ruby con todas sus dependencias incluyendo el Ruby en un ejecutable para windows. En éste artículo voy a comentar RubyScript2Exe de la mano de Erik Veenstra. Mediante ésta libreria, podemos convertir nuestro script a un fichero ejecutable. Realmente lo que sucede es que al iniciar el ejecutable el contenido de éste se vuelca en un directorio temporal y luego se ejecuta con ruby. Podemos parametrizar diferentes constantes de la aplicación para configurar los recursos que queremos que tenga la aplicación (imágenes, ficheros, directorio tempora, etc.). En la misma web de RubyScript2Exe podemos encontrar toda la información al detalle y el funcionamiento de éste script.

En éste enlace, podéis encontrar el enlace directo del script: RubyScript2Exe.rb. Una vez lo hemos guardado en nuestro HD, podemos seleccionar nuestro Script a convertir (en éste caso utilizaré el script que creé hace un par de días, y lo transformaré).

Lo que haré ahora ir a la ruta donde tengo los ejemplos de ruby -> C:\ruby\samples\RubySrc-1.8.6-p111\sample y copiaré allí los ficheros rectangles.rb, rectangles.xml y RubyScript2Exe.rb. Si nos fijamos, en aspecto que tenía el script era éste:

Ahora, para convertir el script tenemos que ejecutar lo siguiente:

ruby rubyscript2exe.rb rectangles.rb

Podemos ver las diferentes ejecuciones en el intérprete de comandos:

Si ahora iniciamos el fichero ejecutable:

Si miramos la carpeta samples, podemos ver como se ha generado el fichero:

Monday, 6 July 2009

Primera toma de contacto con Ruby

Tal como cuenta el Pragmatic Programmer, cada año hay que aprender un lenguaje de programación nuevo. Ya hace tiempo que tenía esta tarea pendiente y ahora que he hecho un poco de tiempo, he creado mi primer script con ruby. El ejemplo muy sencillo consiste en parsear un XML mediante la librería REXML y cargar una serie de registros y realizar un cálculo simple. De esta manera podemos ver si el lenguaje nos gusta, si lo encontramos fácil de manejar y si le podemos sacar provecho. En el mercado existen cientos de lenguajes de programación, y siempre me ha gustado como mínimo crear algo en éstos para ver como resuelven los diferentes problemas que te puedes encontrar con otros lenguajes (Conversiones implícitas, asignaciones, herencia múltiple, etc). El problema radica en que si aprendemos un lenguaje nuevo, tenemos que buscar el "Where to use it?".
Haciendo un poco de historia, Ruby, es un lenguaje de programación interpretado y Orientado a objetos. Éste fue creado por Yukihiro Matsumoto, y presenta trazas de Perl, Python y SmallTalk.
  • Mi Ejemplo:
Éste consiste en una lista de rectángulos los cuáles calcularé su superficie, haciendo una simple multiplicación (altura por anchura). Ésta lista está dentro de un xml, el cuál recorreré mediante la libreria ReXML y mediante el recorrido de los nodos y atributos los meteré dentro de una clase donde se realizará el cálculo. Éste es un ejemplo muy simple el cual nos puede servir para ver que con menos de 30 líneas de código tenemos hecho nuestro Script.

Fichero xml (rectangles.xml):




<rectangles>
<rectangle width="23" height="45" />
<rectangle width="45" height="75" />
<rectangle width="67" height="90" />
<rectangle width="32" height="56" />
</
rectangles>




Programa en Ruby (rectangles.rb):




# Cálculo superfície rectangulos
# @Author : Jordi Coll Corbilla
#-------------------------------------

require "rexml/document"
include REXML

class Rectangulo
def initialize(alto, ancho)
@alto = alto
@ancho = ancho
end

def superficie
puts "Alto #{@alto}, Ancho #{@ancho}, Superficie: " + String(@alto * @ancho)
end
end

#imprimimos el documento completo
doc = Document.new File.new("rectangles.xml")
print doc
print "\n\n"

#realizamos los cálculos
doc = REXML::Document.new File.new('rectangles.xml')
node = doc.elements.to_a("//rectangle")
node.each do |elem|
alto =
Integer(elem.attribute("height").value)
ancho = Integer(elem.attribute("width").value)
rec = Rectangulo.new(alto,ancho)
rec.superficie
rec = nil
end





El resultado de la ejecución:




>ruby rectangles.rb
<rectangles>
<
rectangle height='45' width='23'/>
<
rectangle height='75' width='45'/>
<
rectangle height='90' width='67'/>
<
rectangle height='56' width='32'/>
</
rectangles>

Alto 45, Ancho 23, Superficie: 1035
Alto 75, Ancho 45, Superficie: 3375
Alto 90, Ancho 67, Superficie: 6030
Alto 56, Ancho 32, Superficie: 1792
>Exit code: 0




Como podéis comprobar el script es muy sencillo y por la red podemos encontrar bastantes librerías para hacer el parsing de los xml. En los enlaces de interés hay varios ejemplos. Espero que os sirva de ayuda y a continuar aprendiendo y mejorando!.
  • Enlaces de interés:
Procesando REXML.
Parsing XML Ruby.

Tuesday, 30 June 2009

Concordion

Bueno, este mes ya veo que me estoy superando con la friolera de más de 30 artículos. Espero que os de tiempo de leerlos todos porque ya veis que son muy interesantes. En éste artículo y continuando con mi planificación voy a hablaros de Concordion. Hace unas horas os estuve entreteniendo con FIT (Framework for Integrated Test), pues bién, Concordion es una mejora de éste marco de trabajo y mucho más intuitivo para los lenguages Java, .NET y Ruby. Concordion ha sido desarrollado por David Peterson, y uno de sus desarrolladores es José Manuel Beas, el cual podéis encontrar en mi lista de blog roll. Éste al igual que FIT trabaja mediante tablas HTML, pero es mucho más fácil de añadirlo a nuestro proyecto Java. Mediante una keywords muy básicas, podemos crear nuestras hojas de test para comprobar que el programa devuelve lo que nosotros queremos.
  • Que necesitamos para empezar?
Primero, descargamos la última versión de concordion desde la misma web: Concordion-1.3.1. Luego una vez descargado, tenemos que añadir las librerias necesárias a nuestro class path en el eclipse:

Como podéis observar, tengo enlazadas las librerías concordion-1.3.1.jar, la última versión de la junit (junit-4.6.jar) y las ognl-2.6.9.jar y xom-1.1.jar. Una vez tengo esto, creo un pequeño package llamado example donde pondré el código que voy a probar.
Podréis encontrar más información del funcionamiento de Concordion en la web : http://www.concordion.org/Tutorial.html.

Ahora, aprovechando el código fuente de mi anterior post (Arithmetic.java) crearé un HTML de pruebas para ver si la clase me genera bien los resultados esperados. Aquí os pongo la definición del fichero java:

ArithmeticTest.java:




/**
* @Author : Jordi Coll
* Test With Concordion
*/
package example;

import org.concordion.integration.junit3.ConcordionTestCase;

public class ArithmeticTest extends ConcordionTestCase {
private int x;
private int y;

public int plus () {
return getX() + getY();
}

public int minus() {
return getX() - getY();
}

public int multiply () {
return getX() * getY();
}

public int divide () {
return getX() / getY();
}

public float floating () {
return (float)getX() / (float)getY();
}

public float sin () {
return (float)Math.sin(Math.toRadians(getX()));
}

public float cos () {
return (float) Math.cos(Math.toRadians(getX()));
}

public void setX(int x) {
this.x = x;
}

public int getX() {
return x;
}

public void setY(int y) {
this.y = y;
}

public int getY() {
return y;
}
}





Como podéis ver, hay que heredar de la clase ConcordionTestCase para que parsee el documento HTML y localice las entradas que queremos.

Una vez ejecutamos el proyecto con el jUnit, nos tiene que aparecerer en la ventana resultado:

C:\Temp\concordion\example\Arithmetic.html Successes: 4, Failures: 2, Exceptions: 1

La parte del HTML es muy fácil. Simplemente tenemos que generar éste con una sería de metaKeywords definidos por concordion. De ésta manera, podemos escribir sobre un método y leer de él con mucha facilidad. Por ejemplo voy a cargar los valores x y y con números y luego voy a comprobar el resultado. Si el resultado es correcto, me marcará el número en verde y sino en rojo.

Arithmetic.html:

El HTML se tiene que decir igual que la clase, pero sin el Test, de esta manera el hace el matching de una clase a su HTML correspondiente.




<html xmlns:concordion="http://www.concordion.org/2007/concordion">
<body>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
y:
<span concordion:execute="setY(#TEXT)">2</span>
- x+y:
<span concordion:assertEquals="plus()">4</span>
</p>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
y:
<span concordion:execute="setY(#TEXT)">2</span>
- x*y:
<span concordion:assertEquals="multiply()">4</span>
</p>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
y:
<span concordion:execute="setY(#TEXT)">2</span>
- x div y:
<span concordion:assertEquals="divide()">1</span>
</p>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
y:
<span concordion:execute="setY(#TEXT)">2</span>
- x / y:
<span concordion:assertEquals="floating()">1.0</span>
</p>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
- sin(x):
<span concordion:assertEquals="sin()">0.034899495</span>
</p>
<p>
x:
<span concordion:execute="setX(#TEXT)">2</span>
- cos(x):
<span concordion:assertEquals="cos()">0.99939084</span>
</p>
</body>
</
html>




En el caso de que la prueba tubiese éxito aparecería:


Si uno de los valores no devolviese el valor esperado, nos aparecería de la siguiente manera:

Una de las cosas más interesantes que he visto y que más me ha gustado ha sido el mostrado de los errores. Si nos equivocamos al escribir un método en el HTML, luego en el resultado nos aparece:



FIT (Framework for integrated test)

FIT, o Framework for Integrated Test, es un marco de trabajo para el aprovechamiento integral de los ensayos o pruebas. Es una herramienta open source para la automatización de pruebas del cliente. Integra el trabajo de los clientes, analistas, testers y desarrolladores. FIT mejora la comunicación y la colaboración. Crea un circuito de retroalimentación entre los clientes y programadores y permite a los clientes y los testers utilizar herramientas como Microsoft Office para dar ejemplos de cómo debe comportarse un programa (sin ser programadores). Con ésta utilidad construimos un simple y poderoso puente entre la empresa y el mundo de la ingeniería del software. Mediante FIT, los clientes pueden proporcionar una mayor orientación en el proceso de desarrollo, y obtienen mayor visibilidad sobre lo que está sucediendo en el producto y si están dentro de los límites o no.

  • Cómo funciona?
Los clientes proporcionan ejemplos de cómo el software debería funcionar. Estos ejemplos serán la pasarela entre los programadores y los testers. Mediante tablas en HTML (ya sea utilizando Microsoft Word o Excel y luego guardando el resultado en HTML) FIT comprueba el valor a obtener por el programa y lo compara con el valor de muestra. En el caso de que pase la prueba marca la casilla en verde y sino en rojo. También puede marcarlo en amarillo para indicar otros estados.

FIT fue inventado por Ward Cunningham en el año 2002. Él creó la primera versión de FIT para java y en junio de 2005 se actualizó la versión para Java, C#, Python, Perl, PHP y SmallTalk. Si miramos en la web de FIT, podemos encontrar versiones para Ruby y Delphi (fit4Delphi).
Han aparecido nuevas herramientas como FitNesse o Concordion de los que hablaré más adelante.

Si nos bajamos la última versión para Java (fit-java1.1) encontraremos varios ejemplos y el código fuente de su utilización, podemos iniciar el programa de prueba ejecutando la siguiente línea en el cmd:

java -classpath fit.jar fit.FileRunner examples/input/arithmetic.html results.html

El ejemplo se basa en parametrizar unos valores de prueba para unas operaciones matemáticas y el resultado esperado. Luego mediante FIT se compara que el resultado esperado por el cliente es el resultado mostrado por el programa:

Plantilla:

Se le indica la clase, las operaciones en las columnas y el resultado esperado. Luego una vez ejecutadas las pruebas podemos ver el resultado:



Mock Objects

Continuando en la misma línea del Test Driven Development, existe una evolución o mejora de los xUnit basada en los Mock Objects. Los Mock Objects utilizan una técnica para que el diseño del software se haga sobre el TDD. Al igual que los xUnit, podemos encontrar ésta técnica en varios lenguajes de programación: java (jMock y EasyMock), Delphi (pascalMock), .NET (NMock), etc. Aquí os mostraré un par de ejemplos sobre la implementación en Java y Delphi.
  • Utilizando jMock:
Para este ejemplo, nos descargaremos el jMock de la web en éste caso la versión 2.5.1 (jmock-2.5.1), y la última versión del jUnit (la 4.6) -> jUnit-4.6.jar. Una vez tenemos todos los .jar descargados, tenemos que añadirlos en el class path de nuestro proyecto. Por lo tanto tenemos que vincularlo de la siguiente manera:

Voy a aprovechar el ejemplo que posteé ayer sobre la clase TArithmetic, y la he implementado en java para simular el mismo comportamiento. Además es muy fácil de seguir sin complicar mucho el código.

De acuerdo con el TDD, primero tenemos que crear el test case:




/**
* @Author : Jordi Coll
* Test With Mock Objects
*/
import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class TestJMockIniCase {
@Test
public void testSayGreeting(){
Arithmetic a = new Arithmetic();
assertEquals(0, a.plus());
}
}





En este caso, como no hemos creado la clase Arithmetic da un error. Para hacer que compile, necesito crear la clase. Luego tenemos que crear una clase llamada ComponentArithmetic que es la que comunicará con la clase Arithmetic para entregarle las variables x y y para sus cálculos. Luego explicaremos el porqué de esto.

Aquí está la clase Arithmetic:




/**
* @Author : Jordi Coll
* Test With Mock Objects
*/
public class Arithmetic {
private ComponentArithmetic component;

public void SetComponent(ComponentArithmetic component) {
this.component = component;
}

public int plus () {
return component.getX() + component.getY();
}

public int minus() {
return component.getX() - component.getY();
}

public int multiply () {
return component.getX() * component.getY();
}

public int divide () {
return component.getX() / component.getY();
}

public float floating () {
return (float)component.getX() / (float)component.getY();
}

public float sin () {
return (float)Math.sin(Math.toRadians(component.getX()));
}

public float cos () {
return (float) Math.cos(Math.toRadians(component.getX()));
}
}




Para seguir con la compilación, tenemos que crear la clase ComponentArithmetic. Como queremos utilizar mock objects, debemos crear ésta como una interfaz:




/**
* @Author : Jordi Coll
* Test With Mock Objects
*/
public interface ComponentArithmetic {
public int getX();
public int getY();
}




Uno de los pre-requisitos para el uso de los mock objects, es que la clase que parametrizaremos la tenemos que declarar como una interfaz. Además, tenemos que utilizar métodos setter para inyectar la instancia de ComponentArithmetic a Arithmetic. (No podemos utilizar la notación "new" en una interfaz).

Ahora, solo tenemos que modificar la clase de test para que cumpla con nuestras expectativas:




/**
* @Author : Jordi Coll
* Test With Mock Objects
*/

import org.jmock.Expectations;
import org.jmock.Mockery;

import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMock.class)
public class TestUsingjMock {
//Creamos el contexto para el mock Object
Mockery context = new JUnit4Mockery();

@Test
public void testArithmetic() {
//Mock sobre la clase ComponentArithmetic utilizando la tecnologia de refexión
//La tenemos que definir como variable final
//ya que va a ser utilizada como clase interna
final ComponentArithmetic ca = context.mock(ComponentArithmetic.class);
Arithmetic a = new Arithmetic();
a.SetComponent(ca);

//Ponemos lo que vamos a esperar del mock Object
context.checking(new Expectations() {
{
one(ca).getX();
will(returnValue(2));
one(ca).getY();
will(returnValue(2));
}
});

int plus = a.plus();
//comparamos el resultado con el valor esperado
assertEquals(3, plus);
}
}




(Todo el tema de los expectators lo podemos encontrar en la web del jUnit : http://www.jmock.org/cookbook.html)

Ahora, si ejecutamos el test con el JUnit, obtendremos:

Prueba correcta:

Prueba con error:
  • Utilizando Pascal Mock:
Podemos encontrar la última versión de Pascal Mock en SourceForge. La última versión estable es la 1.1, y podemos descargarla directamente desde aquí. Su utilización es muy parecida al DUnit y hay que generar las interfases necesarias para que los mock object actúen. Podremos encontrar muchos ejemplos dentro del código. El ejemplo que hay dentro del proyecto, lo podemos ejecutar y visualizar:

Es un proyecto que no está muy vivo (desde el 2007 sin ninguna actualización) y es bastante más complicado de utilizar que con java.