Software Reengineering
Juan Carlos Olivares Rojas
MSN: juancarlosolivares@[Link] jcolivar@[Link] [Link] @jcolivares Social Network: Facebook, LinkedIn. G+
Competencias
Especfica: conoce los trminos bsicos de la reingeniera de software y aplica tcnicas de reingeniera para el mejoramiento de software existente as mismo utiliza mejores prcticas para el desarrollo de software. Genricas
Instrumentales: Capacidad de anlisis y sntesis, Solucin de problemas, Toma de decisiones.
Competencias
Interpersonales: Capacidad crtica y autocrtica, Capacidad de trabajar en equipo interdisciplinario, Habilidad para trabajar en un ambiente laboral, Compromiso tico.
Sistmicas: Capacidad de aprender, Capacidad de adaptarse a nuevas situaciones, Capacidad de generar nuevas ideas (creatividad), Habilidad para trabajar en forma autnoma, Preocupacin por la calidad.
Software Hoy en Da
Mito: programadores ahora ya programan como de antes. los de no los
Herramientas ms fciles y productivas El software es cada da ms complejo
Reingeniera del Software
Si su software fuera un edificio, se parecera mas a uno de la izquierda o de la derecha?
Qu malas prcticas de codificacin tendra un edificio como el de la izquierda?
Cdigo mutante Diseo roto El cdigo es antiguo y muy grande Falta de planeacin y documentacin
Problemticas
Software Sustentable
Reducir
Reusar
Reciclar 80% Desarrollo de Software es para mantenimiento. Por lo tanto se necesita de un cdigo simple, legible y bien diseado para que en un futuro pueda ser extensible.
Software Hoy en Da
En el pasado las prioridades eran tener un cdigo rpido, pequeo (ocupa poca memoria), optimizado, utilizando los algoritmos mas eficaces etc... Hoy en da el software es ms complejo pero a la vez hay herramientas ms poderosas, por lo que actualmente el enfoque es que este cdigo tiene que ser simple.
Beneficios Cdigo Simple
El cdigo es mas fcil de cambiar, evolucionar o arreglar (ms del 60% de desarrollo de sw es darle mantenimiento a software existente) Es ms fcil desarrollar de un modo iterativo e incrementando El cdigo es ms fcil de leer (entender).
Reingeniera
Se origin a finales de la dcada de 1980 aunque se populariz en la dcada de 1990.
La reingeniera es un proceso que trata de dar respuesta a una interrogante: Estamos acaso
haciendo las cosas bien o podramos hacerlas mejor? Es el rediseo o cambio drastico de un proceso en un negocio (deriva hacia el producto). Es comenzar de cero, cambio de todo o nada.
Ejemplo de Reingeniera
Reingeniera del Software
La reingeniera de software es costosa y consumidora de tiempo. La reingeniera es una actividad de reconstruccin, preferible de realizar antes de que se derrumbe la obra. Antes de derribar una casa, quizs se necesita corroborar que est mal.
Reingeniera del Software
Reingeniera del Software
La reingeniera es un proceso que altera los elementos internos de toda obra, no es una sola remodelacin de la fallada. La reingeniera ayuda a mantenimiento del software la evolucin y
Generalmente se siguen los siguientes pasos para aplicar reingeniera:
Reingeniera del Software
Reingeniera del Software
Ingeniera Inversa
Se aplica para obtener un modelo detallado de anlisis, ingeniera de requerimientos, diseo y en algunos casos implementacin teniendo una solucin, la cual es una actividad consumidora de tiempo. Tanto la Ingeniera Inversa como la Reingeniera en la mayora de las licencias de Software se encuentran penadas por la ley.
Ingeniera Inversa
Los archivos ejecutables pueden ser desemsamblados obteniendo su cdigo fuente en ensamblador. Los archivos ejecutables con cdigo portable (Java, .NET) pueden ser desemsamblados para obtener su cdigo fuente.
Rediseo
Reuso de Software
El reuso es una de las tcnicas de resolucin de problemas que ms utilizamos los humanos. De hecho es lo primero que verifica nuestro cerebro.
El reuso en software nos ayuda a mejorar la produccin y calidad del software al no reinventar la rueda.
Desafortunadamente reutilizar. no todo se puede
Reuso de Software
La reutilizacin es la propiedad de utilizar conocimiento, procesos, metodologas 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 abstraccin. Entre mayor es su nivel de abstraccin, mayor es su nivel de reuso.
La gran foto
Refactoring
Es modificar el comportamiento interno (generalmente cdigo fuente) sin modificar su comportamiento externo (apariencia, funcionalidad).
Un cambio al sistema que deja su comportamiento inalterable (sin cambios), pero aumenta alguna cualidad no funcional como simplicidad, flexibilidad, comprensin, [Beck, 1999]
Definicin
El trmino se cre como analoga con la factorizacin de nmeros 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 races en -1 y +1) El libro de Martin Fowler Refactoring es la referencia clsica (1999).
Qu es esto?
f(z) = sin(x)cos(y)
Otro modelo
Bad Smells
BAD SMELL REFACTORING PROPUESTO Algunas ideas sobre que reestructura
CODIGO DUPLICADO EXTRAER EL MTODO SUBIR VARIABLES SUSTITUIR EL ALGORITMO EXTRAER EL MTODO INTRODUCIR OBJETOS COMO PARMETROS REEMPLAZAR EL MTODO CON UN OBJETO MTODO
MTODOS LARGOS
CLASES GRANDES
EXTRAER CLASES EXTRAER SUBCLASES MOVER MTODO COLAPSAR JERARQUAS
CARACTERSTICA DE LA ENVIDIA CLASES PEREZOSAS
Ejemplo Renombrar Mtodos
Cul de los dos cdigos siguientes es lo ms correcto? Caso1: double calcRngMaxPer() { .... } Caso 2: double calcularRangoMaximoPermitido() { ....
Ejemplo Renombrar Mtodos
Por qu? Cmo puede observarse en algunas situaciones las recomendaciones de refactoring pueden ser algo subjetivas.
Para este caso se recomienda el caso 2 ya que es ms representativo el nombre del mtodo. Se abreviaba generalmente en el pasado debido a las restricciones de los lenguajes con el tamao de los identificadores, actualmente ya no es tanto problema.
Ejemplo nmeros mgicos
Cambiar nmeros mgicos por constantes.
El cambio de valor de un nmero mgico implica un cambio en todo el cdigo con su prdida de tiempo.
class CalculoSimple { public static double CalcularCincunferencia (double diametro) { return 3.14 * diametro; } }
Ejemplo nmeros mgicos
Cmo debe de quedar la reestructuracin?
class CalculoSimple { public const double PI = 3.14; public static double CalcularCincunferencia (double diametro) { return PI * diametro; } }
En qu lenguaje est este cdigo?
Existen muchas herramientas de reestructuracin de cdigos para los principales lenguajes: Java
Xrefactory, RefactorIT, jFactor, IntelliJ IDEA
Herramientas de Refactoring
C++
CppRefactory, Xrefactory
C#
C# Refactoring Tool, C# Refactory
Los principales IDEs las contienen de forma natica
Herramientas de Refactoring
NetBeans: RefactorIT Oracle Jdeveloper: RefactorIT Borland Jbuilder: RefactorIT
Eclipse: built-in (propia) Emacs: Xrefactory Visual Studio .NET: C# Refactory
Slo soportan refactoring primitivo:
Herramientas de Refactoring
Refactorizacin de clases (Aade (sub)clases a la jerarqua, renombra, elimina clases). Reestructuracin de mtodos (aade a una clase, renombra, elimina, mueve hacia abajo, hacia arriba, aade parmetros, extrae cdigo.
Reestructuracin de variables (aade a una clase, renombra, elimina, cambia modificadores, mueve de lugar.
cundo se debe refactorizar?
Aplicar la Regla de Tres:
[Link] aadir una nueva funcionalidad
[Link] se necesita localizar un error [Link] revisin de cdigo
Codificar este modelo
Una vez desarrollado el modelo, probar con los siguientes valores e indicar su resultado: 6 19 28 43 118
Prctica
Los resultados obtenidos deben de ser: 6 es perfecto 19 no es perfecto 28 es perfecto 43 no es perfecto 118 no es perfecto
Prctica
Una vez desarrollado el modelo, Detectas alguna mala prctica de programacin? Al parecer en algo tan pequeo podra ser que no existieran malos diseos o prcticas de programacin
Prctica
import [Link].*; public class programa1 { public static void main (String[] args){ int Num=[Link](JOptionP [Link]("Introduce numero")); int i=1; int suma=0;
Prctica
while(i<=(Num/2)){ if(Num%i==0){ suma+=i; i+=1;} else{ i+=1;} } if(Num==suma) [Link] og(null,"El numero "+Num+" es un nmero perfecto");
Prctica
else [Link] (null,"El numero "+Num+" no es un nmero perfecto"); }}
Prctica
No tomar en cuenta el mal sangrado
En realidad hay algunas.
La primera de ellas es la conjuncin o mezcla de la lgica de la aplicacin con la presentacin.
Un objeto debe de realizar solo las cosas pertinentes al objeto.
Prctica
Para solucionar esta problemtica podemos aplicar el principio de separacin de interfaces; para ello, realizar lo siguiente: Reestructurar para tener siguiente firma de mtodo: public boolean esPrimo(int n){ la
Prctica Refactoring
Prctica de Refactoring
return true/false
}
En el mtodo main(){} hacer las adecuaciones necesarias para la lectura de datos, la invocacin de la funcionalidad y la impresin de resultados
Prctica de Refactoring
Cmo visualizas la aplicacin?Crees que aun se pueda mejorar? En general tenemos una pequea clase que implementa la lgica y la presentacin. Si bien es cierto que ya est separada aun est en la misma clase
Prctica de Refactoring
Para ello, refactorizaremos a la siguiete arquitectura: App +main(String args):void Numero +esPerfecto(int):boolean
Estndares de Codificacin
Para la reestructuracin de cdigos se pueden seguir convenciones ya definidas las ms importantes son la notacin hngara y la notacin de camello.
La notacin hngara fue creada por Charles Simonyi de Microsoft, el cual es hngaro y por eso recibi ese nombre.
Notacin Hngara
Es un mtodo ampliamente usado sobre todo para convencin 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 programacin.
Notacin Hngara
Descripcin Descripcin Carcter con signo Carcter sin signo Entero Palabra (entero sin signo) Doble palabra (entero 32 bits) Largo Flotante Doble Cadena terminada en /0 Estructura Abc Abr c b n w dw l f d sz sA Objeto (parecido a las estructuras) Manejador (handler) Puntero a entero de 16 bits Puntero largo (32 bits) Enumeraciones Puntero largo a una cadena terminado en nulo Puntero largo a una funcin que devuelve un entero Abr o* h p lp e lpsz Descripcin Formulario CheckBox Botn Imagen Etiqueta Men PictureBox lpfn TextBox ComboBox Lnea Abr frm chk cmd img lbl mnu pic txt cbo lin
Notacin Hngara
int nTest; long lTemp; char *szString = "Prueba"; struct Rect srRect; int nMiVariableEjemplo; char szEjemploString; int NNOMBREINVALIDO; int nNombre_Incorrecto;
Notacin de Camello
Es la utilizada por Java y herramientas afines. Su uso est creciendo en popularidad mientras que la notacin hngara va en desuso. Su principal caracterstica consiste en que no separa nombres de identificadores (variables, mtodos, objetos) con _ para palabras compuestas.
Notacin de Camello
Los identificadores tienen la forma de la joroba de un camello. No se indican tipos de datos. Sigue respetando mucho de la Notacin C. Los mtodos inician en minsculas y si hay una palabra compuesta esta inicia con mayscula dando la apariencia de una joroba.
Notacin de Camello
Las clases inician con mayscula siguiendo el mismo mtodo. Los mtodos para acceder a atributos de las clases no pblicos deben llamarse por convencin set y get.
Convenciones de Desarrollo
Algunas compaas como Google proponen sus propios estndares de codificacin: [Link] Los lenguajes que maneja son C/C++, Python, Perl, Objective-C, XML, entre otros. Estos estndares son manejados en forma obligatoria para el desarrollo de sus proyectos.
Pasos en la reestructuracin
Un paso a la vez
De pasos sencillos (refactorings) se logra mejorar sustancialmente el cdigo fuente. Mejorar el diseo una vez que se ha escrito el cdigo
Pasos
Escribir pruebas unitarias y funcionales. (Se es muy riesgoso si no se tienen) Refactorizar los principales fallos de diseo. Refactorizar un malor olor aunque sea sencillo y probar.
Metodologa
Cuando se desarrollo software utilizando mtodos giles, el tiempo de desarrollo se divide en dos:
Metodologa
[Link] nuevas funcionalidades
[Link]
Cuando se agrega nueva funcionalidad no se modifica cdigo existente, la nica forma de medir el avance es a travs de pruebas unitarias. Cuando se refactoriza, no se agregas pruebas unitarias
Metodologa
Al realizar cambios en el cdigo, la estructura de software es modificada y por lo tanto es necesario refactorizar.
Metodologa
A continuacin se detalla un pequeo ejercicio aplicando el refactoring de Encapsulated Field
Los pasos a seguir son:
Crear los modos get y set para cada atributo que se desea acceder.
Ejercicio
Localizar todas las referencias y reemplazar todos los accesos a los campos con los mtodos get y todas las asignaciones con set.
Compilar y cambiar despus de cada referencia.
Ejercicio
Declarar el campo como privado.
Compilar y probar. Inicialmente se tiene el siguiente cdigo:
Ejercicio
public class Persona { public String name } Se tiene la siguiente prueba unitaria @Test public void prueba(){
Ejercicio
Person person; [Link] = Juan Prez; assertEquals(Juan Prez, [Link]); } Despus se aplica el paso 1 (crear mtodos get y set):
Ejercicio
public class Person { public String name; public String getName() {return name;} public String setName(String NewName){ name=NewName; }
Ejercicio
Ahora se aplica el paso 2: Encontrar todos los clientes; reemplazar referencias con llamadas. Se modifica la primera referencia. Antes: [Link] = Juan Prez; Despus: [Link](Juan Prez);
Ejercicio
Se compila y prueba. Ahora se sigue con la reestructuracin de la siguiente referencia:
Antes: assertEquals( Juan Prez, [Link]); Despus: assertEquals( Juan Prez, [Link]());
Ejercicio
Se compila y vuelve a probar. Una vez que se ha probado que funciona se sigue el paso 4 de hacer privado el campo:
public class Person{ private String name; }
Ejercicio
Patrn de Diseo
Par Problema-Solucin. Mejores prcticas.
Patrn Singletn Problema: se admite exactamente una instancia de una clase. Los objetos necesitan un nico punto de acceso global.
Solucin: Defina un mtodo esttico de la clase que devuelva el Singleton
Singleton
Singleton
public class Singleton { private static Singleton INSTANCE = null; private Singleton() {} private synchronized static Singleton createInstance() { if (INSTANCE == null){ INSTANCE = new Singleton(); } return INSTANCE; }
Patrn de Diseo de un Men
Patrn MVC
Antipatrones de Diseo
Antipatrn es un patrn de diseo que invariablemente conduce a una mala solucin para un problema. Al documentarse los antipatrones, adems de los patrones de diseo, se dan argumentos a los diseadores de sistemas para no escoger malos caminos, partiendo de documentacin disponible en lugar de simplemente la intuicin.
Antipatrones de Diseo
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 intuicin. Adems proporciona una denominacin comn a problemas que facilita la comunicacin entre diferentes desarrolladores.
Antipatrn BLOB
Mejor conocido como objeto todopoderoso. Se presenta cuando una clase es muy grande tanto en atributos y/o en mtodos. Entre ms grande son las clases es ms difciles de mantener, reusar y probar. Su gran tamao puede perjudicar el tiempo de carga. Generalmente son el resultado de un mal diseo o de sistemas legados.
Antipatrn BLOB
Antipatrn BLOB
Antipatrn BLOB
Ofuscacin
La ofuscacin permite ocultar cdigo y en algunos casos reducir el tamao del mismo, lo cual es muy til en lenguajes de script (HTML por ejemplo)
La ofuscacin al igual que el refactoring se puede hacer sobre las estructuras de datos. Por ejemplo en arreglos:
Tc, de Ofuscacin
Arreglos
Tec. de Ofuscacin
Tambin clases:
se
puede
ofuscar
Tec. de Ofuscacin
Clases
Tec. de Ofuscacion
Variables
Tec de Ofuscacin
Variables
Tec. de Ofuscacin
Sobre el flujo del programa
Tec. de Ofuscacin
Sobre el flujo del programa
Tec. de Ofuscacin
Sobre el flujo del programa
Tec. Ofuscacin
Paralelizacin
Paralelizacin
Tec. de Ofuscacin
Paralelizacin
Tec. de Ofuscacin
Ciclos
Tec. de Ofuscacin
Ciclos
Tec. de Ofuscacin
Lo ms adecuado es realizar la ofuscacin sobre el cdigo objeto generado sin alterar el original.
Tc. De Ofuscacin
Existen ofuscadores como proguard, yguard que son libres o comerciales como Dasho o KlassMaster
Substitucin de Algoritmo
Interfaz vs Clase Abstracta
Las clases abstractas como su nombre lo indica son clases que no pueden instanciar objetos. Por este motivo slo se utilizan para definir taxonoma de clases.
Las interfaces definen las carctersticas de una clase pero no la implementan. Las interfaces sirven para manejar herencia mltiple.
Interfaz vs Clase Abstracta
Un futbolista tiene ciertas carctersticas 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 mtodos abstractos o no. Cuando un mtodo es abstracto debe ser redefinido en la subclase.
Interfaz vs Clase Abstracta
Las interfaces todos sus mtodos son abstractos. Una interface no encapsula datos. Cmo se implementara en Java?
Sintactic Sugar
Azcar Sintctico
Es una facilidad dada por los desarrolladores del lenguaje para escribir menos. El ejemplo ms sencillo es el operador ++, C++ es equivalente a C=C+1 Ciclo for (implementacin while)
Azcar Sintctico
IF como operador ternario ?: Goto en java, etiquetas:
public static void imprimir(String ... cadenas) { for (String cadena : cadenas) [Link](cadena); } }
Azcar Sintctico
Boxing automtico de Datos Primitivos a Objetos: Integer a int Anotaciones: @deprecated Arreglos Triangulares Uso de objetos y mtodos Thread-safe
Referencias
Roger S. Pressman, Ingeniera de software un enfoque [Link]. McGraw Hill. Piattini M.G. y F.O, Calidad en el desarrollo y mantenimiento del software. Ed. RAMA. Fowler, M. (1999), Refactoring, Adison-Wesley.
Preguntas?