Refactoring Reuso y Realidad M C Juan Carlos

  • Slides: 43
Download presentation
Refactoring, Reuso y Realidad M. C. Juan Carlos Olivares Rojas Mayo 2011

Refactoring, Reuso y Realidad M. C. Juan Carlos Olivares Rojas Mayo 2011

Agenda • Generalización* • Refactorizaciones mayores* • Rechazo a la reestructuración • Implicaciones concernientes

Agenda • Generalización* • Refactorizaciones mayores* • Rechazo a la reestructuración • Implicaciones concernientes al reuso de software • La realidad de la reestructuración

Competencia Específica • conocerá el impacto de la reestructuración en el reuso de software,

Competencia Específica • conocerá el impacto de la reestructuración en el reuso de software, así como la realidad actual de la aplicación de la misma en el ámbito de desarrollo de software.

Criterios de Evaluación • 100% Ensayo sobre refactoring en la realidad.

Criterios de Evaluación • 100% Ensayo sobre refactoring en la realidad.

Generalización

Generalización

Categorías de Refactoring • Refactorizar para generalizar

Categorías de Refactoring • Refactorizar para generalizar

Categorías de Refactoring • Reestructurar para generalizar

Categorías de Refactoring • Reestructurar para generalizar

Introducir Aserción • Malor olor: un código hace un asunción sobre el estado del

Introducir Aserción • Malor olor: un código hace un asunción sobre el estado del programa. • Desodorante: hacer explícita la asunción a través de un aserción. • Por ejemplo en cierto tipo de validaciones como la raíz cuadrada asumimos que el dato introducido es positivo.

Introducir Aserción • ¿Hay aserciones en java?

Introducir Aserción • ¿Hay aserciones en java?

Introducir Aserción • Si. El código anterior es en C# • Cuando una aserción

Introducir Aserción • Si. El código anterior es en C# • Cuando una aserción falla se produce una excepción “unchecked” • Indican errores de programación (que deben ser corregidos, no capturados). • De hecho, normalmente las aserciones se desactivan en el código de producción.

Aserciones en Java • Las aserciones sólo están disponibles a partir de JDK 1.

Aserciones en Java • Las aserciones sólo están disponibles a partir de JDK 1. 4, si se desea hacer una aserción se deberá de lanzar una excepción: • if (! (estamos_como_queremos) ) throw new Error("fallo en tal zona del programa"); • Pero este esquema maneja banderas lo cual se acaba de ver que no es nada bueno.

Aserciones en Java • En su lugar se puede manejar: • assert estamos_como_queremos; •

Aserciones en Java • En su lugar se puede manejar: • assert estamos_como_queremos; • El cual evaluará la expresión indicada para obtener un valor de verdad. • Las aserciones han caído en desuso con la extensa proliferación de frameworks para pruebas unitarias donde se hacen aserciones: assert. Equals() por ejemplo.

Aserciones en Java • IMPORTANTE: las validaciones de datos no son aserciones!!! • Las

Aserciones en Java • IMPORTANTE: las validaciones de datos no son aserciones!!! • Las validaciones de datos se deben de hacer. Una aserción en teoría es para indicar una porción de código que no debiera de ejecutarse. • Para indicar la versión de java al momento de compilar se deberá habilitar la opción –source seguido del numero de versión.

Aserciones en Java • IMPORTANTE: el contenido colocado en assert no debe de ser

Aserciones en Java • IMPORTANTE: el contenido colocado en assert no debe de ser vital para la ejecución del código. • Suponga el siguiente código: public int calcular. Salario(int comisiones){ assert comisiones >=0; return 1000+(comisiones*20); }

Aserciones en Java • Y el siguiente método para probarlo: public static void main(String

Aserciones en Java • Y el siguiente método para probarlo: public static void main(String args[]){ int comisiones = 5; int sueldo = calcular. Salario(comisiones); System. out. println(“Sueldo=”+ sueldo); } • Si se corre tanto para valores de 5 y -5 para comisiones no sucede nada. ¿Por qué?

Aserciones en Java • Se ocupa activar las directivas del manejo de aserciones: •

Aserciones en Java • Se ocupa activar las directivas del manejo de aserciones: • -ea: activa aserciones • -da: desactiva aserciones • CONSEJO: en caso de duda siempre meter aserciones.

Actividad • Realizar el programa (modificar si ya lo tienen) de la obtención de

Actividad • Realizar el programa (modificar si ya lo tienen) de la obtención de ecuaciones de segundo grado por fórmula general, para que maneje aserciones. • Se deberá contar con un método main() y con interface de usuario • ¿cuántas aserciones manejaste?

Manejo de Errore con try-catch • Cuando se está en fase de producción es

Manejo de Errore con try-catch • Cuando se está en fase de producción es muy común sustituir las aserciones y pruebas unitarias con bloques try-catch imprimiendo la traza del error en pantalla o un archivo. • Realizar está acción de esta forma no es buena práctica de programación. El atrapar excepciones es para darles solución aunque en algunos casos como abrir o crear un archivo sean excepciones mortales.

Manejo de Errore con try-catch • Cuando se está en fase de producción es

Manejo de Errore con try-catch • Cuando se está en fase de producción es muy común sustituir las aserciones y pruebas unitarias con bloques try-catch imprimiendo la traza del error en pantalla o un archivo. • Realizar está acción de esta forma no es buena práctica de programación. El atrapar excepciones es para darles solución aunque en algunos casos como abrir o crear un archivo sean excepciones mortales.

Manejo de Errore con try-catch • Otra mala práctica de programación es atrapar Excepciones

Manejo de Errore con try-catch • Otra mala práctica de programación es atrapar Excepciones genéricas (objeto de la clase Exception) si bien es cierto que nos permiten ahorrar en muchas ocasiones tiempo hacen que el software no sea predecible. Se pueden utilizar considerando las demás excepciones. • Siempre hay que saber que tipos de errores se pueden presentar y darles un tratamiento.

Manejo de Errore con try-catch • Parte de las malas prácticas del uso de

Manejo de Errore con try-catch • Parte de las malas prácticas del uso de trycatch en lenguajes con marcado de errores implícito como Java es el hecho que al forzarnos a atrapar el error solamente lo hacemos para que corra el programa y no en si por manejar el error. En algunas ocasiones no siempre es obligatorio. • Se recomienda lanzar errores en métodos que implementen el modelo, mientras que en la interfaz se deben atrapar.

Manejo de Errore con try-catch • Por cada excepción que se lance debe de

Manejo de Errore con try-catch • Por cada excepción que se lance debe de haber una parte donde se atrape. Por tal motivo es una mala práctica de programación poner una excepción en el método main(). • Se recomienda crear nuestros propios manejadores de errores extendiendo de la clase Exception y colocando aquellos métodos y atributos para procesar el error.

Actividades • Modificar el programa anterior (raíces de una ecuación cuadrática) para que maneje

Actividades • Modificar el programa anterior (raíces de una ecuación cuadrática) para que maneje excepciones y haga las validaciones respectivas. • Se contará con una interfaz con JOption. Pane. • Las entradas se validarán para que al encontrarse un error se marque una excepción creada por nosotros.

Actividades • Para posteriormente procesarlas en la interfaz. • Al introducir un valor incorrecto

Actividades • Para posteriormente procesarlas en la interfaz. • Al introducir un valor incorrecto se deberá quedar en donde está el error para volver a introducir la entrada. • Las clases Excepciones a Generar son: No. Polinomio. Cuadrado cuando a=0 y Raiz. Imaginaria cuando el discriminante es <0.

Ref. en el manejo de Herencia • La generalización es una herramienta muy potente

Ref. en el manejo de Herencia • La generalización es una herramienta muy potente que nos permite evitar mucha duplicación de código. Utilizándola correctamente podemos conseguir que nuestro código sea muy fácil de extender. En estas refactorización encontramos: • • Subir Atributo, Subir Metodo, Subir Codigo. Constructor Bajar Atributo,

Ref. en el manejo de Herencia • • Bajar Metodo, Extraer Subclase Extraer Superclase,

Ref. en el manejo de Herencia • • Bajar Metodo, Extraer Subclase Extraer Superclase, Extraer Interfaz, Agrupar Jerarquia, Sustituir Herencia Por Delegacion, Sustituir Delegacion Por Herencia • En el caso de los refactorins de subir y bajar tanto campos como atributos ya se han comentado con anterioridad.

Pull Up Constructor Body • Problemática: se tiene constructores en las subclases donde prácticamente

Pull Up Constructor Body • Problemática: se tiene constructores en las subclases donde prácticamente es el mismo código. • Solución: crear un constrctor de la clase. Llamarlo desde las subclases. class Manager extends Employee. . . public Manager (String name, String id, int grade) { _name = name; _id = id; public Manager (String name, String id, int _grade = grade; grade) { } super (name, id); _grade = grade; }

Pull Up Constructor Body • Motivación: Los constructores son engañosos. No son totalmente métodos,

Pull Up Constructor Body • Motivación: Los constructores son engañosos. No son totalmente métodos, por lo que su uso es restringido y delicado. • ¿Por qué es necesario definir primero el constructor de la superclase en la subclase? • porque al crear una instancia de una clase, se ejecuta primero el constructor de su superclase, y después el de ella misma.

Extract Subclass • Problemática: Una clase tiene características que son usadas sólo en algunas

Extract Subclass • Problemática: Una clase tiene características que son usadas sólo en algunas instancias. • Solución: Crear una subclase para este subconjunto de características. Trabajo get. Total. Price get. Unit. Price get. Employee Trabajo get. Total. Price get. Unit. Price Labor get. Unit. Price get. Employee

Extract Subclass • Motivación: El principal motivo para utilizar esta refactorización, es que una

Extract Subclass • Motivación: El principal motivo para utilizar esta refactorización, es que una clase tenga comportamiento que es usado por algunas instancias de la clase y no se use para el resto. • La principal alternativa para esta refactorización es Extract Class. Esto significa seleccionar entre delegación y herencia. • Extract subclass es usualmente simple para realizar, pero tiene sus limitaciones.

Extract Superclass • Problema: se tienen dos clases con características similares • Solución: crear

Extract Superclass • Problema: se tienen dos clases con características similares • Solución: crear una superclase y mover las características comunes a la superclase. Department get. Total. Annual. Cost() get. Name() get. Head. Count() Employee get. Total. Annual. Cost() get. Name() getld() Party get. Total. Annual. Cost( ) get. Name( ) Department Employee get. Head. Count( ) getld( )

Extract Superclass • Motivación: el código duplicado es una de las principales cosas malas

Extract Superclass • Motivación: el código duplicado es una de las principales cosas malas en los sistemas. • Una forma de código duplicado es tener dos clases que hacen cosas similares de la misma manera o de distinta manera. Los objetos proporcionan mecanismos de ‘construcción’ para simplificar esta situación con herencia.

Extract Interface • Problema: Varios clientes usan el mismo subconjunto de una interface, o

Extract Interface • Problema: Varios clientes usan el mismo subconjunto de una interface, o dos clases tienen parte de sus interfaces en común • Solución: Extraer el subconjunto dentro de una interface

Extract Interface • Employee get. Rate() has. Special. Skill() get. Name() get. Department() <<interface>>

Extract Interface • Employee get. Rate() has. Special. Skill() get. Name() get. Department() <<interface>> Billable get. Rate( ) has. Special. Skill( ) Employee get. Rate() has. Special. Skill() get. Name() get. Department()

Extract Interface • Motivación: • Las clases son usadas por otras en diferentes maneras,

Extract Interface • Motivación: • Las clases son usadas por otras en diferentes maneras, por lo que son implementadas de forma diferente para cada clase. • Cuando una clase necesita comportamientos de más de una clase, se soporta con lo que se llama Herencia múltiple. Java tiene herencia simple, pero permite establecer e implementar esta clase de requerimientos usando interfaces.

Interfaz vs Clase Abstracta • Las clases abstractas como su nombre lo indica son

Interfaz vs Clase Abstracta • Las clases abstractas como su nombre lo indica son clases que no pueden instanciar objetos. Por este motivo sólo se utilizan para definir taxonomía de clases. • Las interfaces definen las carácterísticas de una clase pero no la implementan. Las interfaces sirven para manejar “herencia múltiple”.

Interfaz vs Clase Abstracta • Un futbolista tiene ciertas carácterísticas que no necesariamente definen

Interfaz vs Clase Abstracta • Un futbolista tiene ciertas carácterísticas que no necesariamente definen su personalidad. Una persona puede tener el comportamiento de un futbolista. Por este motivo no heredan sino que implementan una interfaz. • Las clases abstractas pueden tener métodos abstractos o no. Cuando un método es abstracto debe ser redefinido en la subclase.

Interfaz vs Clase Abstracta • Las interfaces todos sus métodos son abstractos. Una interface

Interfaz vs Clase Abstracta • Las interfaces todos sus métodos son abstractos. Una interface no encapsula datos. • ¿Cómo se implementaría en Java?

Colapse Hierarchy • Problema: Una superclase y una subclase no son muy diferentes •

Colapse Hierarchy • Problema: Una superclase y una subclase no son muy diferentes • Solución: mezclar las clases Empleado Vendedor

Colapse Hierarchy • Motivación: Refactorizar una jerarquía a menudo involucra subir métodos y campos,

Colapse Hierarchy • Motivación: Refactorizar una jerarquía a menudo involucra subir métodos y campos, así como bajar la jerarquía en cuanto a niveles. • Se tienen que encontrar las subclases que no están añadiendo algún valor, y es necesario mezclarlas con otra.

Colapse Hierarchy • MECANISMO: • Selecciona que clase será eliminada: la superclase o alguna

Colapse Hierarchy • MECANISMO: • Selecciona que clase será eliminada: la superclase o alguna subclase. • Utilizar subir campo o método, bajar campo o método, para mover comportamientos y datos, de la clase eliminada a la clase con la que será mezclada.

Colapse Hierarchy • Compilar y probar cada movimiento. • Ajustar las referencias a la

Colapse Hierarchy • Compilar y probar cada movimiento. • Ajustar las referencias a la clase que será eliminada para usar la clase mezclada. Esto afectará declaraciones de variables, tipos de parámetros y constructores. • Eliminar la clase vacía. • Compilar y probar

Dudas

Dudas