Introducci�n - PowerPoint by UUzgpZav

VIEWS: 17 PAGES: 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 mejorarQUÉ ES NECESARIA LA
        ¿POR 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    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

								
To top