Introducción
M.C. Juan Carlos Olivares Rojas
[email protected]
http://antares.itmorelia.edu.mx/~jcolivar/
[email protected]
@jcolivares
Enero 2010
Competencias
• Específica: conoce los términos básicos de la
reestructuración de código e identifica el
problema de código mal desarrollado en el
contexto de desarrollo de software.
• Genéricas
• Instrumentales: Capacidad de análisis y
síntesis, Solución de problemas, Toma de
decisiones.
Competencias
• Interpersonales: Capacidad crítica y autocrítica,
Capacidad
de
trabajar
en
equipo
interdisciplinario, Habilidad para trabajar en un
ambiente laboral, Compromiso ético.
• Sistémicas: Capacidad de aprender, Capacidad
de adaptarse a nuevas situaciones, Capacidad
de generar nuevas ideas (creatividad),
Habilidad para trabajar en forma autónoma,
Preocupación por la calidad.
Temario
• Definición
• Construyendo
desarrollado.
código
sobre
• Pasos de la reestructuración
• Problemas de la reestructuración
código
ya
Evidencias
• 10% Importancia de la Reestructuración de
códigos
• 25% Prácticas
• 5% Otras actividades en el aula
• 60% Examen
Refactoring
• ¿Si su software fuera un edificio, se parecería
mas a uno de la izquierda o de la derecha?
Definición
• Refactoring (Reestructuración) es modificar el
comportamiento interno (generalmente código
fuente) sin modificar su comportamiento
externo (apariencia, funcionalidad).
• Si se llega a modificar su comportamiento
externo formalmente no se le considera
“refactorización”
sino
más
bien
una
modificación.
Definición
• Es hacer un cambio a la estructura interna del
software para hacer más fácil su comprensión,
y más barato para modificar, todo esto sin
cambiar su comportamiento externo [Fowler,
1999] .
• Una transformación del programa de source-tosource preservando su comportamiento
[Roberts1998].
Definición
• Un cambio al sistema que deja su
comportamiento inalterable (sin cambios), pero
aumenta alguna cualidad no funcional como
simplicidad, flexibilidad, comprensión, … [Beck,
1999]
• El término se creó como analogía con la
factorización de números y polinomios. Por
ejemplo, x² − 1 puede ser factorizado como (x +
1)(x − 1), revelando una estructura interna que
no era visible previamente (como las dos raíces
en -1 y +1)
Definición
• No es nada nuevo bajo el sol, se ha llevado a
cabo de manera informal durante años
• La tesis doctoral de William F. Opdyke (1993)
es el primer trabajo conocido que examina
específicamente esta técnica
• El libro de Martin Fowler Refactoring es la
referencia clásica (1999) que trajo está
constumbre al desarrollo de software actual.
Uso de Refactoring
• Aplicaciones como el edificio de la derecha
padecen de malas prácticas en el desarrollo de
software como:
•
•
•
•
“Código mutante”
“Diseño roto”
El código es antiguo y muy grande
Falta de planeación y documentación
• ¿El softwre sufre degeneración?
• Sí
¿Por qué el sw se degenera?
• Hay que cumplir con la fecha de entrega
comprometida, es LA PRIORIDAD NUMERO
UNO!
• Las estimación no fueron confiables
• Aparecen “Expertos” o “Dueños” de código
• !Es un circulo vicioso¡
• El proyecto adquiere “deuda tecnologica”
Software Hoy en Día
• En el pasado las prioridades eran tener un
código rápido, pequeño (ocupa poca memoria),
optimizado, utilizando los algoritmos mas
eficaces etc...
• Hoy en día el software es más complejo pero a
la vez hay herramientas más poderosas, por lo
que actualmente el enfoque es que este
código tiene que ser simple.
Carácterísticas Código Simple
• Funciona bien
• Comunica lo que esta haciendo
• No tiene duplicación
• Tiene un numero menos posible de clases y
métodos, y los que existen están bien
estructurados
• !No es tan fácil y barato ser minimalista!
Beneficios Código Simple
• El código es mas fácil de cambiar, evolucionar
o arreglar (más del 60% de desarrollo de sw es
darle mantenimiento a software existente)
• Es más fácil desarrollar de un modo iterativo e
incrementando
• El código es más fácil de leer (entender).
Beneficios Código Simple
• Es mas fácil hacerlo bien desde la primera, asi
estamos programando mas rápido.
• Las metodologías ágiles como XP y Scrum la
recomiendan.
Ejemplo 1 Getter/Setter
• Hay un atributo público en una clase
• Hacerlo privado y proporcionar
públicos
accesos
Ejemplo 1 de Refactoring
• La reestructuración de códigos está basada en
técnicas probadas por otras personas que en
muchas ocasiones se dan como leyes pero que
es necesario entender para mejorar nuestra
práctica de programación.
• Reflexionemos. ¿Por qué hacer esto?
• Por que el profe de POO no los dijo
• Por que el de reestructuración me va a trabar
en el examen
Ejemplo 1 Getter/Setter
• Por
definición,
los
objetos
tienen
propiedades/carácterísticas/atributos
(variables) que son propias y que no deben de
ser modificables por otros, incluso objetos del
mismo tipo.
• Si una persona tiene un atrbuto peso este no
puede ser modificado al azar (una persona
tiene 60 kilos y de repente ya 65) sólo a través
de un comportamiento/hablidad (método) como
hacerEjercicio() o comerGolosinas().
Ejemplo 1 Getter/Setter
• ¿Esto implica que cada atributo de la clase
debe tener métodos get/set?
• No, sólo aquellos elementos que deban sr
modificados en el exterior. Es como el caso de
los métodos privados.
• ¿En que ocasiones se recomienda que los
atributos de una clase sean públicos?
• Cuando son constantes numéricas.
Ejemplo 2 Encapsulamiento
• La mayoría de las reestructuraciones de
códigos existentes se basan en principios
fundamentales de programación: como la
herencia, el polimorfismo y la encapsulación.
• ¿por qué encapsular? El estado de
Encapsulamiento incrementa modularidad, y
facilita el reuso y mantenimiento de código.
• La representación interna puede ser cambiada
sin modificar la interface externa.
Actividad
• Se necesita implementar una clase rectángulo
para un programa tipo “Paint”. Trate de utilizar
encapsulamiento para modelar la clase si se
considera que tiene los métodos área(),
mover().
• Escriba su solución en un pedazo de hoja de
papel con su nombre.
Solución
• General:
• Atributos: x1,y1, x2, y2: int
• Óptimas:
• Atributos: ancho, alto: int
• Origen: punto
• Atributos: esqSupIzq, esqInfDer: punto
Solución
• Clase: Punto
• Atributos: X, Y: int
• Métodos: getX(), setX(), getY(), setY(): int
• Debemos de quitarnos la idea de que si
compila y el programa hace lo que debe de
hacer no implica que el software esté realmente
correcto.
Ejemplo 3 Renombrar Métodos
• ¿Cuál de los dos códigos siguientes es lo más
correcto?
• Caso1:
double calcRngMaxPer() {
.... }
• Caso 2:
double calcularRangoMaximoPermitido() {
....
Ejemplo 3 Renombrar Métodos
• ¿Por qué?
• Cómo
puede
observarse
en
algunas
situaciones las recomendaciones de refactoring
pueden ser algo subjetivas.
• Para este caso se recomienda el caso 2 ya que
es más representativo el nombre del método.
Se abreviaba generalmente en el pasado
debido a las restricciones de los lenguajes con
el tamaño de los identificadores, actualmente
ya no es tanto problema.
Ejemplo 4 números mágicos
• Cambiar números mágicos por constantes.
• El cambio de valor de un número mágico
implica un cambio en todo el código con su
pérdida de tiempo.
class CalculoSimple {
public static double CalcularCincunferencia
(double diametro)
{ return 3.14 * diametro; }
}
Ejemplo 4 números mágicos
• ¿Cómo debe de quedar la reestructuración?
class CalculoSimple {
public const double PI = 3.14;
public static double CalcularCincunferencia
(double diametro)
{ return PI * diametro; }
}
• ¿En qué lenguaje está este código?
Ejemplo 5 ¿?
• Es correcto el siguiente modelo
• ¿Se puede mejorar?¿cómo?
Ejemplo 5 ¿?
• Si. Subiendo el método a la clase padre
• ¿En qué casos no sería conveniente esta
refactorización?
• Cuando los métodos difieren en su
implementación. ¿Pero aun así es mala?
Ejemplo 5 ¿?
• ¿Cómo se solucionaría?
• Subiendo el método pero sin implementarlo en
la clase padre y sobreescribiéndolo en las
clases hijas.
• La refactorización es parte importante del
proceso de reingeniería y puede enfocarse a la
reestructuración de códigos
Importancia Refactoring
¿POR QUÉ
ES NECESARIA
LA
• Para mejorar
el diseño
del software
REFACTORIZACIÓN?
• Para reducir:
– Decadencia /Envejecimiento del software
– Complejidad del software
– Costos de mantenimiento
• Para incrementar
– Comprensión del software
• Para facilitar futuros cambios
Reingeniería
• La refactorización es parte importante del
proceso de reingeniería y se enfoca
principalmente a la reestructuración de códigos.
• La reingeniería de software es costosa y
consumidora de tiempo.
• La reingeniería es una actividad de
reconstrucción, preferible de realizar antes de
que se “derrumbe” la obra.
Reingeniería
• Antes de derribar una casa, quizás se necesita
corroborar que está mal.
• La reingeniería es un proceso que altera los
elementos internos de toda obra, no es una
sola remodelación de la fallada.
• Generalmente se siguen los siguientes pasos
para aplicar reingeniería:
Técnicas de Reingeniería
• Análisis de Inventario
• Reestructuración de Documentos
• INGENIERÍA INVERSA
• Reestructuración de Códigos
• Reestructuración de Datos
• Ingeniería directa
Ingeniería Inversa
• Se aplica para obtener un modelo detallado de
análisis, ingeniería de requerimientos, diseño y
en algunos casos implementación teniendo una
solución, la cual es una actividad consumidora
de tiempo.
• Tanto la Ingeniería Inversa como la
Reingeniería en la mayoría de las licencias de
Software se encuentran penadas por la ley.
Ingeniería Inversa
• Los
archivos
ejecutables
pueden
ser
desemsamblados obteniendo su código fuente
en ensamblador.
• Los archivos ejecutables con código portable
(Java, .NET) pueden ser desemsamblados
para obtener su código fuente.
Desarrollo de Sw Sustentable
• Dentro de la Teoría del Desarrollo Sustentable
se maneja el enfoque de las tres R’s para ser
más amigables con el medio ambiente y tener
un desarrollo integral.
•
•
•
•
¿Cuáles son esas tres R’s?
Reducir
Reutilizar
Reciclar
Desarrollo de Sw Sustentable
• La primera de ellas Reducir es quizás la más
significativa para logar nuestro objetivo de un
código simple.
• El Reciclaje es quizás el más dificil de lograr
pero a través de técnicas de Reingeniería
podemos volver a emplear cosas como el
código, el modelado, la documentación y el
proceso de desarrollo mismo.
Reuso de Software
• El reuso es una de las técnicas de resolución
de problemas que más utilizamos los humanos.
De hecho es lo primero que verifica nuestro
cerebro.
• El reuso en software nos ayuda a mejorar la
producción y calidad del software al “no
reinventar la rueda”.
• Desafortunadamente
reutilizar.
no
todo
se
puede
Reuso de Software
• La reutilización es la propiedad de utilizar
conocimiento, procesos, metodologías o
componentes de software ya existente para
adaptarlo
a
una
nueva
necesidad,
incrementando significativamente la calidad y
productividad del desarrollo.
• Para que un objeto pueda ser reusable se
necesita de un alto nivel de abstracción. Entre
mayor es su nivel de abstracción, mayor es su
nivel de reuso.
Reuso de Software
• Tipos de reuso:
• Código reciclado: utilizar parte del código
definido en otros proyectos. No es copy &
paste. La idea es tener bibliotecas/API’s del
código.
• Componentes de código: consiste en utilizar
módulos, clases, APIs, etc.
• Esquemas: DFD, Diagramas UML.
Herramientas de Refactoring
• Existen
muchas
herramientas
de
reestructuración de códigos para los principales
lenguajes:
• Java
– Xrefactory, RefactorIT, jFactor, IntelliJ IDEA
• C++
– CppRefactory, Xrefactory
• C#
– C# Refactoring Tool, C# Refactory
Herramientas de Refactoring
• Los principales IDE’s las contienen de forma
natica
• NetBeans: RefactorIT
• Oracle Jdeveloper: RefactorIT
• Borland Jbuilder: RefactorIT
• Eclipse: built-in (propia)
• Emacs: Xrefactory
• Visual Studio .NET: C# Refactory
Herramientas de Refactoring
• Sólo soportan refactoring primitivo:
• Refactorización de clases (Añade (sub)clases a
la jerarquía, renombra, elimina clases).
• Reestructuración de métodos (añade a una
clase, renombra, elimina, mueve hacia abajo,
hacia arriba, añade parámetros, extrae código.
• Reestructuración de variables (añade a una
clase,
renombra,
elimina,
cambia
modificadores, mueve de lugar.
Actividad
• En equipos de tres personas seleccionadas por
el profesor, determinar el catálogo de
refactorizaciones realiza una herramienta como
NetBeans.
• Para ello se deberá abrir el IDE de NetBeans y
ubicarse en el menú de Refactoring anotar el
nombre de cada refactorización y dar una breve
descripción de cada una de ellas.
Actividad
• Algunas refactorizaciones son muy simples y
su nombre prácticamente las describe, otras
tendrán que investigarse.
• Entregar un breve reporte en formato PDF
indicando además la separación de trabajos.
Entregarlo antes de que se acabe la clase al
correo del profesor.
• Se revisará que estén todas y cada una de las
refactorizaciones (no hay que dar ejemplos).
Solución al Refactoring
• ¿Si se codifica bien desde el principio no se
tendría que reestructurar el software?
• Sólo serían muchos menores los cambios
• La solución para el buen desarrollo de software
son los patrones de diseño.
• Es una solución bien documentada que los
expertos aplican para solucionar nuevos
problemas porque han sido utilizadas con éxito
en el pasado.
Solución al Refactoring
• Los expertos identifican partes de un problema
que son similares a otros problemas que han
sido encontrados anteriormente.
• Recuerdan la solución aplicada y la generalizan
(objetivo del refactoring).
• Adaptan la solución general al contexto del
problema actual (extensión del refactoring).
Solución al Refactoring
• Los patrones de diseño son el objetivo de
refactorizar el código, pero identificar el
resultado de la refactorización es solo una
parte del problema; transformar el código es
otro reto.
REFACTORIZACIÓN
PATRONES DE
DISEÑO
Solución al Refactoring
• Los patrones están especificados siguiendo un formato
estándar:
1. Nombre
2. Tambien conocido como
3. Propiedades—Tipo, Nivel
4. Propósito ---¿Para que sirve?
5. Presentación --- Problema que soluciona (con ejemplos)
6. Aplicabilidad --- Cuando y por qué debería usarse
7. Descripción --- Que hace y como se comporta de forma detallada
8. Implementación ---¿Cómo implementarlo?
9. Ventajas e inconvenientes
10.Variantes
11.Patrones relacionados
12.Ejemplo
Solución al Refactoring
• Los patrones suponen una evolución en
abstracción y reutilización del software.
– Abstracción Resolución de problemas complejos
dividiéndolos en otros más simples.
– Reutilización Si ya se resolvió un problema, se
pueden
reutilizar
sus
funciones,
librerías,
algoritmos, etc.
Patrones de Diseño
• Realizar un programa que permita que un
momento dado uno y solo un objeto pueda
estar en ejecución (no se permiten dos o más
ejemplares).
• La utilización de patrones puede resolver este
problema. Caso de ejemplo: Singleton
• Algunas APIs están implementadas bajo
patrones de diseño. Por ejemplo algunos tipos
de ventana en Swing.
Singleton
• Problema: se admite exactamente una
instancia de una clase. Los objetos necesitan
un único punto de acceso global.
• Solución: Defina un método estático de la clase
que devuelva el Singleton
Singleton
Singleton
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton() {}
private
synchronized
static
void
createInstance() {
if (INSTANCE == null){
INSTANCE = new Singleton();
}
}
Patrón de Diseño de un Menú
Actividad
• Modificar el patrón singleton para que permita
que un objeto se pueda crear un número
específico de veces (por ejemplo de 3 a 5)
• ¿Cómo quedaría dicho patrón?
• Tarea: traer un programa con orientación a
objetos de más de 200 LOC. Mañana por email antes de las 13:00 horas.
Antipatrones de Diseño
• Antipatrón es un patrón de diseño que
invariablemente conduce a una mala solución
para un problema.
• Al documentarse los antipatrones, además de
los patrones de diseño, se dan argumentos a
los diseñadores de sistemas para no escoger
malos caminos, partiendo de documentación
disponible en lugar de simplemente la intuición.
Antipatrones de Diseño
• El estudio de los antipatrones es muy útil
porque sirve para no escoger malos caminos
en el desarrollo de sistemas, teniendo para ello
una base documental y así evitar usar
simplemente la intuición. Además proporciona
una denominación común a problemas que
facilita la comunicación entre diferentes
desarrolladores.
Antipatrón BLOB
• Mejor conocido como “objeto todopoderoso”.
Se presenta cuando una clase es muy grande
tanto en atributos y/o en métodos.
• Entre más grande son las clases es más
difíciles de mantener, reusar y probar. Su gran
tamaño puede perjudicar el tiempo de carga.
Generalmente son el resultado de un mal
diseño o de sistemas legados.
Antipatrón BLOB
Antipatrón BLOB
Antipatrón BLOB
Antipatrones de Diseño
• Algunos autores consideran al Singleton
(Simplicidad) un ejemplo de un antipatrón ¿por
que?
• Se tiene que estudiar el código para ver las
dependencias en lugar de simplemente ver las
interfaces de nuestras clases.
• Dificulta las pruebas de código ya que
promueve un alto acoplamiento.
Antipatrones de Diseño
• Los singleton permiten controlar las instancias
de nuestras clases, esto no está bien porque
una clase solo debe tener responsabilidades de
negocio. Para controlar la creación de clases
deberemos usar un patrón Factoría sobre las
clases de negocio.
• En general su naturaleza estática y pública no
son del todo bien vistas.
Práctica 1
• ¿cuál es la reestructuración de código más
simple que existe?
• Aquella que no modifica en nada realmente el
código fuente
• Entonces, ¿cuál sería?
• La documentación del código en el código.
• Se recomienda autodocumentar el código para
un más fácil entendimiento del mismo.
Práctica 1
• Dado un proyecto en Java que carece de
documentación se deberá realizar lo siguiente:
• Autodocumentación del código fuente usando
javadoc. Dicha documentación debe de estar
en inglés. Se deberá documentar cada clase,
atributo de clase y método. Colocar
comentarios adicionales en el código para
hacerlo más legible. Valor 25%.
Práctica 1
• Mostrar la arquitectura del sistema (por ejemplo
un Diagrama de Clases). Pueden auxiliarse de
una herramienta de ingeniería inversa. Valor
10%
• De los métodos de cada clase realizar su
modelado
(por
ejemplo
diagrama
de
actividades, de flujo, etc.). Valor 25%
• Mostrar como interactúan las clases entre sí
(diagrama de comunicación, etc.). Valor 10%
Práctica 1
• En base a lo que se ha visto que malas
prácticas
detectas
y
cómo
podrían
reestructurarse. Sino existen malas prácticas
demuestra y justifica el por que. Valor 30%
Javadoc
• Es el estándar para crear documentación para
los proyectos en Java.
• Es una herramienta estándar del JDK de Sun
Microsystem. Crea documentación en HTML y
casi cualquier IDE lo hace.
• Se deben utilizar los comentarios especiales /**
…..*/ con algunas palabras clave para
determinar la documentación.
Javadoc
• Las palabras clave inician con una arroba.
• Se puede incrustar cualquier etiqueta de HTML
para hacer más visible la documentación.
• @author nombre_desarrollador
• @deprecated descripción //indica un método
que no se utiliza su uso
Javadoc
• @param nombre descripción
• @return descripción //no se debe utilizar con
métodos void.
• @see referencia //asocia con otro elemento el
cual puede ser: #método(); clase#método();
paquete#método(); paquete.clase#método().
• @throws clase descripcion
• @version versión
Javadoc
• La documentación se crea de la siguiente
forma: javadoc archivo.java
• En NetBeans se puede encontrar la opción en
el menú Build en la opción Generate JavaDoc
for …
• Se recomienda realizar tanto el código como
las clases en inglés.
Javadoc
/**
* Thrown to indicate that the application has
attempted to convert
* a string to one of the numeric types, but that the
string does not
* have the appropriate format. *
* @author unascribed
* @version 1.16, 02/02/00
* @see java.lang.Integer#toString()
Javadoc
* @since JDK1.0
*/
public class NumberFormatException extends
IllegalArgumentException {
/**
* Constructs a <code> NumberFormatException
</code> with no detail message.
*/
public NumberFormatException () { super(); }
Javadoc
/**
* Constructs a <code> NumberFormatException
</code> with the
* specified detail message.
* @param s the detail message.
*/
public NumberFormatException (String s) { super
(s); } }
Laboratorio 1
• Se utilizó la herramienta Analyze Javadoc
aunque no es del todo efectiva.
• Sugerencias de refactoring:
• Renombrar los atributos de la clase que
comienzan con _. Renombrar los parámetros
de los métodos o hacer uso del operador this.
Laboratorio 1
• Se pueden utilizar mejores estructuras de datos
tal es el caso de la clase Vector que dobla su
capacidad cuando se acaba su espacio
predeterminado por un List. *
• Utilizar constantes en lugar de números
mágicos.
• El método Statement de la clase Customer
realiza muchas cosas y no todas son
exactamente de la clase. Se tiene que dividir.
Laboratorio 1
• ¿por qué Customer no tiene relación con
Rental?
Laboratorio 1
• ¿Es correcto?
Laboratorio 1
• El retornar un String en el método Statement de
Customer no es una buena opción.
• Un código aparentemente bueno tiene muchas
cosas que se pueden mejorar
Categorías de “Refabricación”
• Existen
muchas
categorías
para
la
reestructuración de códigos. En este curso se
verán tres enfoques: generales, de acuerdo a
Demeyer y según Fowler.
• Generales:
• Basadas en la Granularidad
– Primitivas VS Compuestas
– Pequeñas VS Grandes
Categorías de “Refabricación”
• Basadas en el Lenguaje de Programación
– Lenguajes específicos (Java, Smalltalk, …)
– Independientes del Lenguaje
• Basadas en el grado de Formalidad
– Formal
– No Formal
– Semi-formal
• Basadas en el grado de Automatización
– Totalmente automatizadas
– Interactivas
– Totalmente manuales
Catálogo de Ref. de NetBeans
• Renombrar (Rename)
– Cambia el nombre de una clase
• Mover (move)
– Mueve de forma segura una clase a otra ubicación
• Copiar (copy)
– Copia una clase a otra ubicación
• Eliminar de forma segura (Safely Delete)
– Borra una clases y las referencias a ésta.
Catálogo de Ref. de NetBeans
• Cambiar los parámetros del método (Change
Method Parameters)
– Modifica parámetros de un método
• Ascender (Pull Up)
– Mueve los métodos y campos a una clase que
hereda de su clase actual.
• Descender (Pull Down)
– Mueve las clases internas, métodos y campos para
todas las subclases de la claseactual (a las clases
hijas).
Catálogo de Ref. de NetBeans
• Mover de nivel interior a exterior(move inner to
outer level)
– Toma una clase interna (que se encuentre dentro
de otra) y la saca de ésta para colocarla en su
propio archivo
• Convertir anónimo
annonymus to inner)
en
miembro
(convert
– Sirve para cambiar una clase miembro anónima (no
instanciable) a una clase miembro actual.
Catálogo de Ref. de NetBeans
• Introducir variable (introduce variable)
– Permite introducir una variable e inicializarla a partir
de la selección.
• Introducir constante (introduce constant)
– Introduce una constante al código con su referente
valor y tipo.
• Introducir campo (introduce field)
– Toma una expresión seleccionada y crea un campo
con el valor de la expresión; la cual será
reemplazada con el nombre del campo.
Catálogo de Ref. de NetBeans
• Introducir método (replace block code with a
field)
– A partir de varias líneas de código seleccionadas,
el reestructurador declara un nuevo método y
también se encarga de aplicarlo en lugar de las
líneas.
• Encapsular campos (encapsulate fields)
– Toma las variables seleccionadas y crea métodos
set y get para dicha variable.
Catálogo de Ref. de NetBeans
• Pull Up & Push Down (Ascender y Descender)
– Aplica las dos refactorizaciones en un solo paso
• Extract Interface (Extraer Interface)
– Crea una nueva Interface de los métodos públicos
no estáticos dentro de una Clase o Interface.
Catálogo de Ref. de NetBeans
• Extract Superclass (Extraer superclase)
– Crea una nueva Clase Abstracta, extiende a la
Clase actual la nueva Clase, y mueve los métodos
seleccionados y campos a la nueva Clase.
• Use Supertype Where Possible (usar supertipo
cuando sea psible)
– Convierte el uso de una Subclase a una Superclase
Laboratorio 2
• Dado un código en FORTRAN (muy básico, no
es necesario aprender nada del lenguaje) se
deberá pasar a Java y hacerlo funcionar.
• Para probarlo se realizará una prueba de
unidad con los valores indicados.
• Hacer refactoring de los nombres de variables
del programa. Para ello se deberá entender
que debe de hacer el programa.
JUnit
• Es el framework de pruebas unitarias para Java
más utilizado en el mundo.
• En IDEs como Netbeans y Eclipse viene de
manera predeterminada.
• Para crearlo en Netbeans es muy fácil sólo se
escoge la opción de crear una prueba unitaria
de una clase existente y crea un bosquejo de
prueba con cada método impelementado.
JUnit
• Existen dos versiones populares a manejar la
3.x (anticuada pero ampliamente utilizada) y la
4.x (que maneja anotaciones pero no es
compatible con versiones viejas).
• La ventaja de utilizar pruebas unitarias es que
nos permite corroborar nuestro código sin
necesidad de crear una aplicación.
JUnit
• En la versión 3.x las pruebas unitarias tienen la
siguiente forma:
• Se importa la clase junit.framework.TestCase;
• La clase de prueba hereda de TestCase
• Se puede utilizar utilizar un constructor para
inicializar datos.
JUnit
• Se utiliza el método setUp() para realizar un
conjunto de acciones antes de evaluar un caso
de prueba.
• Se utiliza el método tearDown() para realizar
acciones una vez finalizado el caso de prueba
• Se utiliza el método fail() que recibe una
cadena de mensaje de error para forzar a una
falla.
JUnit
• Se
utiliza
el
método
assertEquals(valoresperado,
valorresultante)
para saber si el método se ejecutó de manera
exitosa.
• Se
puede
utilizar
el
método
assertNotNull(objeto) para saber si un objeto no
es nullo.
• Para tipos de datos flotantes el método
assertEquals utiliza un parámetro adicional
JUnit
• La diferencia con la versión 4.x de Junit radica
en lo siguiente:
• Se
importan
las
siguientes
clases:
org.junit.After,
org.junit.AfterClass,
org.junit.Before,
org.junit.BeforeClass,
org.junit.Test, org.junit.Assert.*;
• Se utilizan las anotaciones @BeforeClass,
@AfterClass, @Before, @After para indicar
cuando se utilizan los métodos auxiliares
JUnit
• La clase de prueba no extiende de ninguna otra
pero cada caso de prueba debe utilizar la
anotación @Test
• Se recomienda realizar los casos de prueba de
manera separada uno por uno y dejarlos
siempre presente.
Laboratorio 2
• Como se pudo observar, una
reestructuraciones
usadas
con
frecuencia es la migración de código.
de las
mayor
• La realización de pruebas unitarias es la norma
en el desarrollo de software moderno.
• La reestructuración de nombres de variables
aunque no es complicada, necesita de conocer
el dominio del problema.
Categorías de Refactoring
• Según Demeyer, existen 3 categorías que
corresponden a evoluciones de diseño
genéricas, que ocurren frecuentemente en los
Sistemas de software Orientados a Objetos:
• Creación de Métodos plantilla
• Optimización de Jerarquías de clases
• Incorporar Relaciones de Composición
Categorías de Refactoring
• Crear Métodos
comportamiento
específicas (n).
de Plantilla:
común (m)
Separar el
de partes
A
A
m
m
n
B
m
this.n
C
m
D
C
B
n
n
super.n
D
Categorías de Refactoring
• Optimización de Jerarquía de Clases: Mejorar
la estructura jerárquica de la clase por medio
de descomponer una clase compleja y grande,
en varias clases pequeñas.
• La clase compleja usualmente incluye tanto
una abstracción general como varios casos
concretos diferentes que son candidatos para
una especialización.
Categorías de Refactoring
• Refactorizar para generalizar
Categorías de Refactoring
• Reestructurar para generalizar
Categorías de Refactoring
• Incorporar relaciones de composición:
• La herencia algunas veces es sobreusada e
incorrectamente utilizada en el modelado de las
relaciones entre las clases.
• La Agregación es otra forma de modelar estas
relaciones.
Categorías de Refactoring
• Refactoring de Agregación:
– Mover las variables/metódos de instancia de una
clase agregada a la clase de uno de sus
componentes.
– Mover las variables/métodos de una clase
componente hacia las clases agregadas que
contienen componentes los cuales son instancias
de la clase componente.
– Convertir una relación, que ha sido modelada
usando herencia, dentro de una agregación y
visceversa.
CATEGORÍAS DE REESTRUCTURACIÓN
• Ejemplo
3. Incorporar relaciones de Composición
Refactoring según Fowler
• Reestructuraciones pequeñas
– Composición/descomposición de métodos (9
reestructuraciones)
– Mover
características
entre
objetos
(8
reestructuraciones)
– Reorganización de datos (16 reestructuraciones)
– Simplificación de expresiones condicionales(8
reestructuraciones)
– Tratar con Generalización (12 reestructuraciones)
– Simplificar
llamadas
a
métodos
(15
reestructuraciones)
Refactoring según Fowler
• Reestructuraciones grandes
– Arreglar problemas de Herencia
– Extraer jerarquías
– Convertir diseño procedural a Objetos
– Separar el dominio de la presentación
Refactorización Pequeña
• Descomposición de Métodos.
• Extracción del método
– Cuando se tiene un fragmento de código que
puede ser agrupado, dentro de un método cuyo
nombre explique el propósito del método.
– PARA QUE??? Para mejorar la claridad y quitar
redundancia.
Refactorización Pequeña
• Descomposición de Métodos.
• Método serial (lo opuesto a extracción de
método)
– Cuando el cuerpo de un método es tan claro como
su nombre, hay que meter el cuerpo del método
dentro del cuerpo de su llamada y hay que eliminar
dicho método.
– PARA
QUE???
Para
eliminar
demasiada
indirección y delegación.
Refactorización Pequeña
• Descomposición de Métodos.
• Variable Temp
– Cuando tienes una variable Temp asignada solo
una vez a una expresión simple, sustituya la
variable Temp por la expresión.
– PARA QUE??? Simplificación
Refactorización Pequeña
• Descomposición de Métodos.
• Reemplazar una Temp con un query(mensaje)
– Cuando utilizas una variable Temp para guardar el
resultado de una expresión, hay que extraer la
expresión dentro de un método y reemplazar todas
las referencias de la variable Temp con una
llamada al método.
– PARA QUE??? Limpiar el código.
Refactorización Pequeña
• Reemplazar una Temp con un Query
• Reemplazar
Refactorización Pequeña
• Descomposición de Métodos
• Introducir variables de Explicación
– Cuando tienes una expresión compleja, introduce el
resultado de la expresión (o partes de ella) en una
variable temporal que explique el propósito..
– PARA QUE??? Reducir la complejidad de las
expresiones para mayor claridad en el código.
Refactorización Pequeña
• Descomposición de métodos
• Fraccionar variables temporales
– Cuando se asigna una variable temporal más de
una vez, pero no es una variable de control (de
ciclo) ni tampoco una variable de alguna colección
(estructura), se debe fraccionar la variable
haciendo una variable diferente para cada
asignación.
– POR QUE??? Utilizar variables temporales más de
una vez (para mas de una cosa) es confuso.
Refactorización Pequeña
• Descomposición de métodos
• Fraccionar variables temporales
Const. cod. sobre cod. Des.
• En el conpceto tradicional de Refactoring se
necesita
que
haya
código
existente
previamente (software legado).
• Las mejores prácticas de reestructuración son
más adecuadas de practicar en el modelado y
en la construcción del software que en su
mantenmiento.
• Se recomienda refactorizar constantemente
Pasos de la reestructuración
• No existen recetas de cocina para lograr la
refactorización de aplicaciones, lo que se debe
de tener bien en claro es el objetivo de por que
es necesario lograr la refactorización.
• Realizar
reestructuración
de
códigos
simplemente por realizarla en muchas casos
puede considerarse un desperdicio.
Pasos de la reestructuración
• Hay dos fases esenciales en el método de
desarrollo iterativo de software (según Foote
and Opdyke, 1995)
– EXPANSIÓN
Añadir nueva funcionalidad
– CONSOLIDACIÓN
Reorganizar y reestructurar el software para hacer
más reusable y más fácil el mantenimiento.
Introducir patrones de diseño
Aplicar Reestructuraciones (refactoring)
Consejos para Reestructurar
• Cuando pienses que es necesario. No sobre
una base periódica
• Aplicar la regla de Tres
– Primera vez: Implementar la solución a partir de
cero
– Segunda vez: Aplicar algo similar por la duplicación
de código
– Tercera vez: No reimplementar o duplicar, sino
Factorizar!!
Consejos para Reestructurar
• Consolidar
después
de
añadir
nueva
Funcionalidad, especialmente cuando la
funcionalidad es difícil de integrar en el código
base existente.
• Durante la depuración (debugging)
– Si es difícil seguir la pista a un error, reestructure
para hacer el código más comprensible.
• Durante la inspección
(revisiones de código)
formal
del
código
Consejos para Reestructurar
• Algunas ideas sobre que reestructura
BAD SMELL
REFACTORING PROPUESTO
CODIGO DUPLICADO
EXTRAER EL MÉTODO
SUBIR VARIABLES
SUSTITUIR EL ALGORITMO
MÉTODOS LARGOS
EXTRAER EL MÉTODO
INTRODUCIR OBJETOS COMO PARÁMETROS
REEMPLAZAR EL MÉTODO CON UN OBJETO
MÉTODO
CLASES GRANDES
EXTRAER CLASES
EXTRAER SUBCLASES
CARACTERÍSTICA DE LA “ENVIDIA”
MOVER MÉTODO
CLASES “PEREZOSAS”
COLAPSAR JERARQUÍAS
Problemas de reestructuración
• La reestructuración de códigos no es una etapa
sencilla requiere de mucha creatividad.
• En
muchas
ocasiones,
malas
reestructuraciones traen consigo más errores y
quizás un rendimiento más pobre.
Estándares de Codificación
• Para la reestructuración de códigos se pueden
seguir convenciones ya definidas las más
importantes son la notación húngara y la
notación de camello.
• La notación húngara fue creada por Charles
Simonyi de Microsoft, el cual es húngaro y por
eso recibió ese nombre.
Notación Húngara
• Es un método ampliamente usado sobre todo
para convención de nombres de variables.
• Consiste en tener variables autodocumentadas
agregando un prefijo de tres caracteres o
menos para indicar su tipo.
• Las abreviaturas de los tipos de datos puede
variar
dependiendo
del
lenguaje
de
programación.
Notación Húngara
Descripción
Abr
Objeto (parecido a
las estructuras)
o*
Manejador
(handler)
h
p
Descripción
Abr
Carácter con signo
c
Carácter sin signo
b
Entero
n
Palabra (entero sin
signo)
w
Puntero a entero de
16 bits
lp
Doble palabra
(entero 32 bits)
dw
Puntero largo (32
bits)
Enumeraciones
Largo
l
Flotante
f
Doble
d
Cadena terminada
en /0
sz
Estructura Abc
sA
Descripción
Abr
Formulario
frm
CheckBox
chk
Botón
cmd
Imagen
img
e
Etiqueta
lbl
Puntero largo a una
cadena terminado
en nulo
lpsz
Menú
mnu
PictureBox
pic
Puntero largo a una
función que
devuelve un entero
lpfn
TextBox
txt
ComboBox
cbo
Línea
lin
Notación Húngara
• int nTest;
• long lTemp;
• char *szString = "Prueba";
• struct Rect srRect;
• int nMiVariableEjemplo;
• char szEjemploString;
• int NNOMBREINVALIDO;
• int nNombre_Incorrecto;
Notación Húngara
• Las funciones o subrutinas no se les agrega
abreviaciones, se recomiendan tengan un
nombre descriptivo.
• Los nombres de las clases van en mayúsculas.
• Se pueden tener nuevos tipos de datos sólo se
deben de poner las nuevas nomenclaturas.
Notación de Camello
• Es la utilizada por Java y herramientas afines.
Su uso está creciendo en popularidad mientras
que la notación húngara va en desuso.
• Su principal característica consiste en que no
separa nombres de identificadores (variables,
métodos, objetos) con “_” para palabras
compuestas.
Notación de Camello
• Los identificadores tienen la forma de la joroba
de un camello. No se indican tipos de datos.
Sigue respetando mucho de la Notación C.
• Los métodos inician en minúsculas y si hay una
palabra compuesta esta inicia con mayúscula
dando la apariencia de una joroba.
Notación de Camello
• Las clases inician con mayúscula siguiendo el
mismo método.
• Los métodos para acceder a atributos de las
clases no públicos deben llamarse por
convención set y get.
Convenciones de Desarrollo
• Algunas compañías como Google proponen
sus propios estándares de codificación:
http://code.google.com/p/google-styleguide/
• Los lenguajes que maneja son C/C++, Python,
Perl, Objective-C, XML, entre otros.
• Estos estándares son manejados en forma
obligatoria para el desarrollo de sus proyectos.
Práctica 3
• Dado un código realizar refactorización para
que los nombres de clases, métodos, atributos,
variables y cualquier otro identificador tengan la
convención híbrida “Camello Húngaro”. Los IDs
tienen que estar en Inglés.
• Del catálogo de refactorizaciones simples
revisa cual de ellos se puede aplicar y realiza la
implementación Requerida.
Referenicas
• Fowler, M. (1999), Refactoring, Adison-Wesley.
• Sanchez, M., (2009), Material del Curso de
Reestructuración
de
Códigos,
Instituto
Tecnológico de Morelia.
Dudas
Descargar

Refactoring