Tdd y clean code SG campus

Preview:

DESCRIPTION

Kent Beck dice “No sé si soy un gran programador, pero definitivamente son un programador con grandes prácticas”. ¿Cuáles son estas grandes prácticas? Test Drive Development y Clean Code son dos de ellas. La adopción de estas prácticas nos ayuda como programadores para que perdamos el miedo a usar código nuevo y confiemos en nuestros compañeros de equipo. También ayuda a reducir la tan odiada documentación o peor, tener documentación incorrecta (como comentarios obsoletos) . Esta presentación incluye una demostración de TDD en Java.

Citation preview

www.sgcampus.com.mx @sgcampus

www.sgcampus.com.mx

@sgcampus

TDD y Clean Code

Por Jorge Jiménez y Fernando Arana

www.sgcampus.com.mx @sgcampus

BAD CODE

¿Quién se identifica con esto?

xkcd.com

www.sgcampus.com.mx @sgcampus

BAD CODE

O peor… ¿A quién le ha pasado?

www.sgcampus.com.mx @sgcampus

BAD CODE

Y entonces…

www.sgcampus.com.mx @sgcampus

¿Existe alguna solución?

¿Extensos estándares? ¿Documentación?

¿Poner extremo cuidado?¿Análisis estático de código?

¿Inspecciones?¿Pedir la bendición para el código productivo?

www.sgcampus.com.mx @sgcampus

Test Drive Development

www.sgcampus.com.mx @sgcampus

Test Drive Development

“No soy un gran programador. Sólo

soy un buen programador con

grandes hábitos”

―Kent Beck

Inventor de TDD

www.sgcampus.com.mx @sgcampus

Test Drive Development

TDD es una técnica de desarrollo que nació con

XP (eXtreme Programming)

Se hace diseño y codificación guiado por las

pruebas unitarias

Con TDD podemos lograr que el diseño “emerja”

del código

www.sgcampus.com.mx @sgcampus

Test Drive Development

Pero antes…

1. Has una lista de las posibles pruebas que se

harán al requerimiento

2. Comienza con las pruebas más sencillas

3. Aquellas que rodean el requerimiento

4. DETÉN el impulso de programar todas las

reglas de negocio en una sola vez

www.sgcampus.com.mx @sgcampus

Test Drive Development

Consta de 3 pasos:

1. Escribes una prueba que falla

2. Escribes el MÍNIMO código productivo que

hace que la prueba pase

3. Haces Refactor usando Clean Code

www.sgcampus.com.mx @sgcampus

Clean Code

“Sabes que estás trabajando con Código Limpio

cuando cada rutina que lees resulta ser

exactamente lo que esperabas de ella”

-Ward Cunningan

“Sabes que ves un Código Limpio cuando:

• Corren todas las pruebas

• No tiene código duplicado

• Expresa todas las ideas que tiene el sistema

• Minimiza el número de entidades como clases,

métodos, y funciones”

-Ron Jeffries

Fuente: libro “Clean Code” por Bob Martin

www.sgcampus.com.mx @sgcampus

Clean Code

www.sgcampus.com.mx @sgcampus

Clean Code

Mapa Mental por

Gustavo García en

base a los videos de

cleancoders.com

www.sgcampus.com.mx @sgcampus

Clean Code

Nombres:

Los nombres deben reflejar su intención

Deben poder pronunciarse

Usar nombres de acuerdo a las reglas de negocio

Evitar encodings (prefijos, tipos de datos)

Algunas reglas de nombrado:

Clases = Sustantivos

Variables = Nombres

Métodos = Verbos

Booleanos = “is” o “has”

www.sgcampus.com.mx @sgcampus

Clean Code

Nombres

VS

Fuente: libro “Clean Code” por Bob Martin

www.sgcampus.com.mx @sgcampus

Clean Code

Funciones:

Deben de ser pequeñas

Y más pequeñas aún: 4 a 6 líneas

Una función larga puede tener algunas clases

escondidas

No pasar más de 2 argumentos

Extraer hasta no poder extraer más, así

aseguramos un nivel de abstracción

“FUNCTIONS SHOULD DO ONE THING. THEY

SHOULD DO IT WELL. THEY SHOULD DO IT ONLY”

Fuente: libro “Clean Code” por Bob Martin

www.sgcampus.com.mx @sgcampus

Clean Code

Formato:

Comentarios: El mejor comentario es el que no se

escribe

Tamaño de archivos: entre más pequeños, mejor

Formato Vertical: uniformidad en interlineado,

sangría, ciclos, etc.

Step Down Rule: Organizar métodos del más

abstracto al más específico.

El código debe entenderse en secuencia de arriba

hacia abajo

Fuente: libro “Clean Code” por Bob Martin

www.sgcampus.com.mx @sgcampus

Clean Code

Fuente: libro “Clean Code” por Bob Martin

www.sgcampus.com.mx @sgcampus

¿Qué es una Kata?

Una Kata es una manera de poner en práctica y

aprender de manera segura

En una Kata, el aprendizaje es más importante

que el resultado (es decir, no importa si el

programa “no jala” o se queda incompleto)

Por eso, las Katas se tienen que hacer más de

una vez

www.sgcampus.com.mx @sgcampus

Kata Factores Primos

Escribe un clase llamada “PrimeFactors” que tiene

un método estático: generate

El método generate toma un argumento entero y

regresa una lista de enteros “List<Integer>” Esta

lista contiene los factores primos en secuencia

numérica.

+ generate(n : int)

Prime Factors

www.sgcampus.com.mx @sgcampus

Productivo

Junit

@Testpublic void dadoUno_regresaVacio() throws Exception {

FactoresPrimos factorador = new FactoresPrimos();List<Integer> factores = factorador.buscarFactoresPrimos(1);assertEquals(0, factores.size());

}

public class FactoresPrimos {

public List<Integer>buscarFactoresPrimos(int i) {return null;

}

}

www.sgcampus.com.mx @sgcampus

Junit

@Testpublic void dadoUno_regresaVacio() throws Exception {

FactoresPrimos factorador = new FactoresPrimos();List<Integer> factores = factorador.buscarFactoresPrimos(1);assertEquals(0, factores.size());

}

Productivo

public class FactoresPrimos {

public List<Integer>buscarFactoresPrimos(int i) {return new ArrayList<Integer>();

}

}

www.sgcampus.com.mx @sgcampus

Junit

private FactoresPrimos factorador;

@Testpublic void setUp() throws Exception {

this.factorador = new FactoresPrimos();}

@Testpublic void dadoUno_regresaVacio() throws Exception {

List<Integer> factores = factorador.buscarFactoresPrimos(1);assertEquals(0, factores.size());

}

www.sgcampus.com.mx @sgcampus

Productivo

Junit

@Testpublic void dadoDos_regresaListaConSoloDos() throws Exception {

List<Integer> factores = factorador.buscarFactoresPrimos(2);assertEquals(1, factores.size());assertEquals(2, factores.get(0).intValue());

}

public List<Integer> buscarFactoresPrimos(int numero) {ArrayList<Integer> listaDeFactores = new ArrayList<Integer>();if (numero > 1) {

listaDeFactores.add(2);}return listaDeFactores;

}

www.sgcampus.com.mx @sgcampus

Productivo

Junit

@Testpublic void dadoTres_regresaListaConSoloTres() throws Exception {

List<Integer> factores = factorador.buscarFactoresPrimos(3);

assertEquals(1, factores.size());assertEquals(3, factores.get(0).intValue());

}

public List<Integer> buscarFactoresPrimos(int numero) {ArrayList<Integer> listaDeFactores = new ArrayList<Integer>();if (numero % 2 == 0) {

listaDeFactores.add(2);} else if (numero % 3 == 0) {

listaDeFactores.add(3);}return listaDeFactores;

}

www.sgcampus.com.mx @sgcampus

Junit

private void assertFactoresPrimos(int numeroAEvaluar) {List<Integer> factores =

factorador.buscarFactoresPrimos(numeroAEvaluar);assertEquals(1, factores.size());assertEquals(numeroAEvaluar, factores.get(0).intValue());

}

@Testpublic void dadoDos_regresaListaConSoloDos() throws Exception {

assertFactoresPrimos(2);}

@Testpublic void dadoTres_regresaListaConSoloTres() throws Exception {

assertFactoresPrimos(3);}

www.sgcampus.com.mx @sgcampus

public List<Integer> buscarFactoresPrimos(int numero) {ArrayList<Integer> listaDeFactores = new ArrayList<Integer>();for (int primo = 2; primo <= numero; primo++) {

añadirPrimo(listaDeFactores, primo, numero);}return listaDeFactores;

}

private void añadirPrimo(ArrayList<Integer> listaDeFactores, int primo, int numero) {if (numero % primo == 0) {

listaDeFactores.add(primo);}

}

Productivo

www.sgcampus.com.mx @sgcampus

Productivo

Junit@Testpublic void dadoCuatro_regresaDosYDos() throws Exception {

List<Integer> factores = factorador.buscarFactoresPrimos(4);assertEquals(2, factores.size());assertEquals(2, factores.get(0).intValue());assertEquals(2, factores.get(1).intValue());

}

public List<Integer> buscarFactoresPrimos(int numero) {int aEvaluar = numero;final ArrayList<Integer> listaDeFactores = new ArrayList<Integer>();for (int primo = 2; primo <= aEvaluar;) {

if (numero % primo == 0) {listaDeFactores.add(primo);aEvaluar = aEvaluar / primo;

} else {primo++;

}}return listaDeFactores;

}

}

www.sgcampus.com.mx @sgcampus

public class FactoresPrimos {

private static final int PRIMER_FACTOR_PRIMO = 2;

public List<Integer> buscarFactoresPrimos(final int numero) {siguientesFatoresPrimos(listaDeFactores, PRIMER_FACTOR_PRIMO, numero);return listaDeFactores;

}

private void siguientesFatoresPrimos(final ArrayList<Integer> listaDeFactores, final int primo, final int numero) {

if (primo <= numero) {evaluaFactorPrimo(listaDeFactores, primo, numero);

}}

private void evaluaFactorPrimo(final ArrayList<Integer> listaDeFactores, final int primo, final int numero) {

if (numero % primo == 0) {listaDeFactores.add(primo);siguientesFatoresPrimos(listaDeFactores, primo, numero /

primo);} else {

siguientesFatoresPrimos(listaDeFactores, primo + 1, numero);}

}}

Productivo

www.sgcampus.com.mx @sgcampus

Productivopublic class FactoresPrimos {

private static final int PRIMER_FACTOR_PRIMO = 2;

public List<Integer> buscarFactoresPrimos(final int numero) {siguientesFatoresPrimos(listaDeFactores, PRIMER_FACTOR_PRIMO, numero);return listaDeFactores;

}

private void siguientesFatoresPrimos(final ArrayList<Integer> listaDeFactores, final int primo, final int numero) {

if (primo <= numero) {evaluaFactorPrimo(listaDeFactores, primo, numero);

}}

private void evaluaFactorPrimo(final ArrayList<Integer> listaDeFactores, final int primo, final intnumero) {

if (numero % primo == 0) {listaDeFactores.add(primo);siguientesFatoresPrimos(listaDeFactores, primo, numero / primo);

} else {siguientesFatoresPrimos(listaDeFactores, primo + 1, numero);

}}

}

www.sgcampus.com.mx @sgcampus

Junit

private void assertFactoresPrimos(final int numeroAEvaluar, final int... valores) {final List<Integer> factores = factorador.buscarFactoresPrimos(numeroAEvaluar);assertEquals(valores.length, factores.size());for (int i = 0; i < valores.length; i++) {

assertEquals(valores[i], factores.get(i).intValue());}

}

@Testpublic void dadoUno_regresaVacio() throws Exception {

assertFactoresPrimos(1);}

@Testpublic void dadoDos_regresaListaConSoloDos() throws Exception {

assertFactoresPrimos(2, 2);}

@Testpublic void dadoTres_regresaListaConSoloTres() throws Exception {

assertFactoresPrimos(3, 3);}

@Testpublic void dadoCuatro_regresaDosYDos() throws Exception {

assertFactoresPrimos(4, 2, 2);}

www.sgcampus.com.mx @sgcampus

Productivo

Junit

@Testpublic void dadoCinco_regresaCinco() throws Exception {

assertFactoresPrimos(5, 5);}

Pasa

www.sgcampus.com.mx @sgcampus

Junit

@Testpublic void dadoUno_regresaVacio() throws Exception {

assertFactoresPrimos(1);}@Testpublic void dadoDos_regresaListaConSoloDos() throws Exception {

assertFactoresPrimos(2, 2);}@Testpublic void dadoTres_regresaListaConSoloTres() throws Exception {

assertFactoresPrimos(3, 3);}@Testpublic void dadoCuatro_regresaDosYDos() throws Exception {

assertFactoresPrimos(4, 2, 2);}@Testpublic void dadoCinco_regresaCinco() throws Exception {

assertFactoresPrimos(5, 5);}

public void dadoNumero_regresaSusFacotresPrimos() throws Exception {assertNumeroGeneraFactoresPrimos(1);assertNumeroGeneraFactoresPrimos(2, 2);assertNumeroGeneraFactoresPrimos(3, 3);assertNumeroGeneraFactoresPrimos(4, 2, 2);assertNumeroGeneraFactoresPrimos(5, 5);

}

private void assertFactoresPrimos(final int numeroAEvaluar, final int... valores) private void assertNumeroGeneraFactoresPrimos(final int numeroAEvaluar, final int... valores)

www.sgcampus.com.mx @sgcampus

Productivo

Junit

Pasan

assertNumeroGeneraFactoresPrimos(6, 2, 3);

assertNumeroGeneraFactoresPrimos(7, 7);assertNumeroGeneraFactoresPrimos(8, 2, 2, 2);assertNumeroGeneraFactoresPrimos(11, 11);assertNumeroGeneraFactoresPrimos(2 * 3 * 5 * 7 * 11 * 13 * 17, 2, 3, 5, 7, 11, 13, 17);

www.sgcampus.com.mx @sgcampus

Conclusiones

Fuente: libro “Clean Code” por Bob Martin

Utilizando TDD y Clean Code tendremos los siguientes beneficios:

Seguridad al modificar código (red de protección de pruebas unitarias)

Código mantenible para poder arreglar bugs o implementar nuevos features

Mejor trabajo en equipo (¡por fin nos entendemos!)

Clientes satisfechos

Estimaciones más certeras

Enfocarnos en cosas más interesantes: nuevos frameworks, Clean Architecture, Patrones, Sistemas resistentes a fallos, Escalabilidad…

www.sgcampus.com.mx @sgcampus

Clean Code

“Deja el código mejor de cómo lo encontraste”

www.sgcampus.com.mx @sgcampus

Bibliografía

Fuente: libro “Clean Code” por Bob Martin

Clean code: A Handbook of Agile Software Craftsmanship

(Robert C. Martin)

Test Driven Development: By Example (Kent Beck)

Refactoring: Improving the Design of Existing Code (Martin

Fowler)

Working Effectively with Legacy Code (Michael Feathers)

The Clean Coder: A Code of Conduct for Professional

Programmers (Robert C. Martin)

The Coding Dojo Handbook (Emily Bache)

CleanCoders.com

Recommended