Está en la página 1de 137

Introducción

M.C. Juan Carlos Olivares Rojas


jcolivar@itmorelia.edu.mx
http://antares.itmorelia.edu.mx/~jcolivar/
juancarlosolivares@hotmail.com
@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 código sobre código ya


desarrollado.

• Pasos de la reestructuración

• Problemas de la reestructuración
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-to-


source 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 accesos
públicos
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
• Para mejorar el diseño
¿POR QUÉ del software
ES NECESARIA LA
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 no todo se puede


reutilizar.
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 e-
mail 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 en miembro (convert


annonymus to inner)
– 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 de las
reestructuraciones usadas con mayor
frecuencia es la migración de código.

• 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 de Plantilla: Separar el
comportamiento común (m) de partes
específicas (n).

A
A
m this.n
m
n

B C D B C D
m m n n super.n
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.
• Ejemplo
CATEGORÍAS DE REESTRUCTURACIÓN
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 formal del código


(revisiones de 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 o*
Descripción Abr
las estructuras)
Carácter con signo c
Manejador h Descripción Abr
Carácter sin signo b (handler)
Formulario frm
Entero n Puntero a entero de p
16 bits CheckBox chk
Palabra (entero sin w
signo) Puntero largo (32 lp Botón cmd
Doble palabra dw bits) Imagen img
(entero 32 bits) Enumeraciones e Etiqueta lbl
Largo l Puntero largo a una lpsz Menú mnu
Flotante f cadena terminado PictureBox pic
en nulo
Doble d TextBox txt
Puntero largo a una lpfn
Cadena terminada sz función que ComboBox cbo
en /0 devuelve un entero Línea lin
Estructura Abc sA
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

También podría gustarte