Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
1. Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
1. Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
1. Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
1. Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
1. Introducci�n
�
Qu� es la refactorizaci�n
�
Un primer ejemplo
2.
Principios de refactorizaci�n
3.
Cuando refactorizar: c�digo sospechoso
4.
Pruebas unitarias y funcionales
5.
T�cnicas de refactorizaci�n
�
Refactorizaciones simples
�
Refactorizaciones comunes
�
Refactorizaci�n y herencia
6. Bibliograf�a
Curso 11-12 2
�
Proceso de mejora de la estructura interna de un
externo no var�a.
�
Es una forma sistem�tica de introducir mejoras en el c�digo
que minimiza la posibilidad de introducir errores (bugs) en �l.
�
Consta b�sicamente de dos pasos
�
Introducir un cambio simple (refactorizaci�n)
�
Probar el sistema tras el cambio introducido
�
Consiste en realizar modificaciones como
�
A�adir un argumento a un m�todo
�
Mover un atributo de una clase a otra
�
Mover c�digo hacia arriba o hacia abajo en una jerarqu�a de herencia, etc.
Curso 11-12 3
� Tenemos una aplicaci�n de un video-club
�
Calcula e imprime el cargo a realizar a un cliente, a partir de las pel�culas que
ha alquilado y el tiempo de alquiler.
�
Hay tres tipos de pel�culas: normales, infantiles y estrenos.
�
La aplicaci�n tambi�n bonifi ca con puntos a los clientes que m�s alquilan.
Curso 11-12 4
while (rentals.hasMoreElements()) {
double thisAmount = 0;
Alquiler each = (Alquiler) rentals.nextElement();
thisAmount += 2;
if (each.getDiasAlquiler() > 2)
thisAmount += (each.getDiasAlquiler() - 2) * 1.5;
break;
case Pelicula.ESTRENO:
thisAmount += each.getDiasAlquiler() * 3;
break;
case Pelicula.INFANTIL:
thisAmount += 1.5;
if (each.getDiasAlquiler() > 3)
. . .
Curso 11-12 5
. . .
// add frequent renter points
frequentRenterPoints++;
// add bonus for a two day new release rental
if ((each.getPelicula().getCodigoPrecio() == Pelicula.ESTRENO)
&& each.getDiasAlquiler() > 1)
frequentRenterPoints++;
totalAmount += thisAmount;
} // END WHILE
return result;
}
2.
Antes de aplicar t�cnicas de refactorizaci�n, debemos asegurarnos de que disponemos
de una bater�a de pruebas robusta y completa. Estas pruebas deben ser auto-
comprobantes (como las pruebas unitarias)
Curso 11-12 9
thisAmount = calculaCargo(each);
. . .
}
switch (alq.getPelicula().getCodigoPrecio()) {
case Pelicula.NORMAL:
cargo += 2;
if (alq.getDiasAlquiler() > 2)
case Pelicula.ESTRENO:
cargo += alq.getDiasAlquiler() * 3;
break;
case Pelicula.INFANTIL:
cargo += 1.5;
if (alq.getDiasAlquiler() > 3)
return cargo;
Curso 11-12 10
-
Hacer que sea m�s sencillo encontrar fallos
�Cuando refactorizar?
Met�fora de los dos sombreros
Cuando trabaja lleva puesto uno (y solo uno) de los dos sombreros.
-
Refactoriza al a�adir un m�todo/funci�n
-
Refactoriza cuando necesites arreglar un fallo
-
Refactoriza al revisar c�digo
Capa de persistencia:
Acoplamiento con bases de datos
Cambios de interfaz
Cuando no refactorizar
Cuando el c�digo original es tan 'malo' (por dise�o,o m�ltiples fallos) que merece
m�s la pena reescribirlo desde el principio.
Algunas ejemplos:
C�digo duplicado: l�neas de c�digo exactamente iguales o muy parecidas en varios
sitios. Se debe unificar en un s�lo sitio. Es el 'mal olor' m�s com�n y se debe
evitar a toda costa.
M�todos muy largos: Cuanto m�s largo es el c�digo, m�s dif�cil de entender y
mantener. Un m�todo muy largo normalmente est� realizando tareas que deber�an ser
responsabilidad de otros. Se deben identificar �stas y descomponer el m�todo en
otros m�s peque�os.
Curso 11-12 15
Clases muy grandes. Clases con demasiados m�todos, demasiados atributos o incluso
demsiadas instancias. La clase est� asumiendo, por lo general, demasiadas
responsabilidades. Se debe identificar si realmente todas esas cosas tienen algo
que ver entre s� y si no es as�, hacer clases m�s peque�as, de forma que cada una
trate con un cojunto peque�o de responsabilidades bien delimitadas (por ejemplo,
ocuparse de la conexi�n con una base de datos, o manejar cierto tipo de informaci�n
espec�fica, como fechas, DNI, etc.)
Curso 11-12 16
Los test o pruebas unitarios son una forma de probar el correcto funcionamiento de
un m�dulo de c�digo. Esto sirve para asegurar que cada uno de los m�dulos funcione
correctamente por separado.
La idea es escribir casos de prueba para cada funci�n no trivial o m�todo en el
m�dulo o paquete, de forma que cada caso sea independiente del resto.
Las pruebas funcionales tratan a un componente software como una caja negra.
Verifican una aplicaci�n comprobando que su funcionalidad se ajusta a los
requerimientos o a los documentos de dise�o. Se trata a la aplicaci�n o componente
software como un todo.
Curso 11-12 19 Para que una prueba unitaria sea buena se deben cumplir los
siguientes requisitos:
Profesionales: las pruebas deben ser consideradas igual que el c�digo, con la misma
profesionalidad, documentaci�n, etc.
Curso 11-12 20
Las condiciones o valores l�mite con los que un m�todo debe ejecutarse.
Curso 11-12 21
http://junit.sourceforge.net/
En C++, existen varias librer�as similares a Junit en Java:
Cxxtest : http://cxxtest.tigris.org/ (GNU LGPL)
CppUnit : https://launchpad.net/cppunit2 (GNU LGPL)
En C#,
Nunit : http://www.nunit.org/ (licencia tipo BSD)
CsUnit : http://www.csunit.org/ (licencia zLib)
Curso 11-12 23
T�cnicas de refactorizaci�n Refactorizaciones simples A�adir un par�metro Quitar un
par�metro Cambiar el nombre de un m�todo Curso 11-12 24
A�adir un par�metro
Motivo: Un m�todo necesita m�s informaci�n al ser invocado
Soluci�n: A�adir como par�metro un objeto que proporcione dicha
informaci�n
Ejemplo
Cliente.getContacto() . Cliente.getContacto(Fecha f)
Observaciones
Evitar listas de argumentos demasiado largas.
Curso 11-12 25
Quitar un par�metro
Motivo: Un par�metro ya no es usado en el cuerpo de un m�todo
Soluci�n: Eliminarlo
Ejemplo
Cliente.getContacto(Fecha f) . Cliente.getContacto()
Observaciones
Si el m�todo est� sobrescrito, puede que otras implementaciones del m�todo s� lo
usen. En ese caso no quitarlo. Considerar sobrecargar el m�todo sin ese par�metro.
Curso 11-12 26
Cliente.getLimiteCreditoFactura()
Observaciones
Curso 11-12 27
Refactorizaciones comunes
�
Mover un atributo
�
Mover un m�todo
�
Extraer una clase
�
Extraer un m�todo
�
Cambiar condicionales por polimorfi smo
�
Cambiar c�digo de error por excepciones
Curso 11-12 28
Mover un atributo
Motivo: Un atributo es (o debe ser) usado por otra clase m�s que en la clase donde
se defi ne. Soluci�n: Crear el atributo en la clase destino
Observaciones
Curso 11-12 29
Mover un atributo
Ejemplo
class Cuenta {
private TipoCuenta tipo;
private double tipoInteres;
Curso 11-12 30
Ejemplo
Cliente.getLimCrdFact() .
Cliente.getLimiteCreditoFactura()
Observaciones
Si es parte de una interface publicada, crear un nuevo m�todo con el nuevo nombre y
el cuerpo del m�todo. Anotar la versi�n anterior como #deprecated y hacer que
invoque a la nueva.
Curso 11-12 31
Mover un m�todo
Motivo: Un m�todo es usado m�s en otro lugar que en la clase actual Soluci�n: Crear
un nuevo m�todo all� donde m�s se use.
Ejemplo
Cliente.getLimiteCreditoFactura()
Cuenta.getLimiteCreditoFactura(Cliente c)
// arg. opcional, s�lo en caso de necesitar info. de
Cliente
Observaciones
Observaciones
Curso 11-12 33
Curso 11-12 34
Extraer un m�todo
Motivo: Existe un fragmento de c�digo (quiz�s duplicado) que se puede agrupar en
una unidad l�gica.
Soluci�n: Convertir el fragmento en un m�todo cuyo nombre indique su prop�sito e
invocarlo desde donde estaba el fragmento.
Ejemplo: (ejemplo de la introducci�n de la UD)
Observaciones
Curso 11-12 35
Curso 11-12 36
Ejemplo:
double getSalario() {
switch(tipoEmpleado()) {
case INGENIERO: return salarioBase + productividad; break;
case VENDEDOR: return salarioBase + ventas*comision; break;
case DIRECTOR: return salarioBase + bonificacion+ dietas; break;
default : throw new RuntimeException(�Tipo de empleado incorrecto�);
}
}
Curso 11-12 37
Curso 11-12 38
Curso 11-12 40
�
Refactorizaci�n y herencia
�
Generalizar un m�todo
�
Especializar un m�todo
�
Colapsar una jerarqu�a
�
Extraer una clase derivada
�
Extraer una clase base (o interfaz)
�
Convertir herencia en composici�n
Curso 11-12 41
Generalizar un m�todo
Motivo: Existen dos o m�s m�todos con id�ntico comportamiento
(c�digo duplicado) en las clases derivadas.
Caso particular: un m�todo en clase derivada sobrescribe uno de la clase base pero
hace esencialmente lo mismo.
Curso 11-12 42
Curso 11-12 43
Especializar un m�todo
Motivo: Un comportamiento de la clase base s�lo es relevante para algunas clases
derivadas.
Soluci�n: Mover el m�todo que lo implementa a las clases derivadas.
Ejemplo
Empleado.getCuotaVentas() . Vendedor.getCuotaVentas()
Observaciones
Curso 11-12 44
Observaciones
Curso 11-12 45
Curso 11-12 48
Hay que prestar especial atenci�n a qu� m�todos deben subir a la base ('generalizar
m�todo')
Curso 11-12 49
Extraer una superclase
Ejemplo:
Curso 11-12 50
Curso 11-12 51
Curso 11-12 53
Otras refactorizaciones
Existen otras muchas refactorizaciones que no se presentan aqu�:
Eliminar setters
etc, etc,...
Curso 11-12 54
Conclusiones
http://www.dwheeler.com/innovation/innovation.html
Curso 11-12 55
En esta unidad docente no se ha hecho especial hincapi� en los pasos a seguir para
realizar las refactorizaciones de forma controlada. Una lectura imprescindible para
conocer estos detalles es el libro de Martin Fowler:
Martin Fowler. Refactoring. Improving the Design of Existing Code Addison Wesley,
2007
http://martinfowler.com/refactoring/
Curso 11-12