Vous êtes sur la page 1sur 133

“Bad Smells” en código

M.C. Juan Carlos Olivares Rojas

Febrero 2011
Agenda
• Código Duplicado

• Métodos grandes

• Clases grandes

• Lista de Parámetros excesiva

• Características de la “envidia”
Agenda
• Sentencias Switch

• Jerarquías de Herencia Paralelas

• Campos Temporales

• Encadenamientos de mensajes
Agenda
• Clases alternativas con diferentes
interfaces

• Librerías de clases incompletas


•aprenderá e
identificará los malos
Competencia

hábitos de codificación
(bad smells),
conociendo así los
errores que
generalmente se
cometen al desarrollar
código.
Criterios de Evaluación
• 70% Examen práctico

• 30% Desarrollo de portafolio de


evidencias (trabajos, tareas y
prácticas)
Código Duplicado
• Un “bad smell” es una mala
práctica de programación que
debe de ser eliminada para

Bad Smells
que el código sea más legible
y por ende más mantenible.

• Los refactoring funcionan


como desodorante
permitiendo que sea mejor la
programación.
• Si algo huele mal…

• Muy probablemente este

Badsmell
mal.

• La codificación deficiente
trae consigo una serie de
características que la
evidencian rápidamente.
• Los “malos olores” son visto
como signos de debilidad del
código.

Badsmell
• En general, para cada “mal
olor” existe una serie de
refactorings propuesto para
solucionarlos.
Malos Olores
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


Código Duplicado
• Es el principal indicador de
un malor olor.

• ¿cómo detectamos código


duplicado?
• Misma expresión en dos

Código Duplicado
métodos de la misma clase.

• Misma expresión en dos


subclases hermanas.

• Códigos que sean similares,


pero no iguales.
• Métodos que hagan lo

Código Duplicado
mismo con diferente
algoritmo.

• Duplicidad de código en dos


clases independientes.

• La gran mayoría de los “Bad


Smells” se da por la
“codificación excesiva”
• La codificación excesiva se

Código Duplicado
da por muchas razones:
malos hábitos de
programación, presión del
tiempo de desarrollo, etc.

• La decisión de reestructurar
código depende de los
desarrolladores.
• Aunque no está enfocado
directamente con la
codificación, es el principal mal

Mal Diseño
olor en la implementación del
software.

• Generalmente no se hace diseño


y cuando llega a hacerse se
hace muy superficial sólo por
cumplir el requerimiento.
• En un diagrama de clases en
UML es posible verificar

Mal Diseño
algunos indicadores de
malos olores y poder
reestructurarlos antes de
codificarlos.
• Existirán indicadores que no
son muy visibles en el
modelado como los métodos

Mal Diseño
largos o el código duplicado.

• Se pueden utilizar otros


diagramas de UML como los
de secuencia, actividades,
estados, etc.
Práctica 3
• TDD (Test-Driven Development)
es una metodología de diseño la
cual consiste en codificar en
principio las pruebas unitarias del
código.

• Se diseñan todos los posibles


casos de prueba y se verifican sus
resultados.

Práctica 3
• Se codifican las pruebas
unitarias y hasta que no se
pasen al 100% el programa no
puede terminar.

• Nótese que al inicio las


pruebas no pueden correrse
hasta que se ejecute el código.

Práctica 3
• Los malos olores también

Código Duplicado
pueden ser determinados a
través de herramientas
automatizadas, generalmente
conocidos como analizadores
de códigos.

• Una herramienta popular es


PMD que puede analizar
código escrito en Java
• ¿Si se codifica bien desde el

Patrones de Diseño
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.
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.
• Los patrones suponen una

Patrones de Diseño
evolución en abstracción y
reutilización del software.

• Los patrones de diseño


están basados en esquemas
que funcionan. ¿Cómo es
una casa estilo americano?
• Realizar un programa que

Patrones de Diseño
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
• Problema: se admite
exactamente una instancia
de una clase. Los objetos
Singleton

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
• Realizar el análisis del programa Criba cn
la herramienta PMD a nivel máximo y
tratar de minimizar la mayor cantidad de
errores posibles
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.
Métodos Grandes
• El tener métodos grandes trae
consigo muchas consecuencias
como el hecho de que es
menos reusable y más dificil
de leer.

• Se recomienda que los


métodos no sean mayores a
24 líneas

Métodos grandes
• El número de líneas puede ser
variable pero se recomienda
que se pueda leer en una sola
pantalla.

• Es deseable que los métodos


no sea tan cortos para evitar el
seguir el flujo del programa

Métodos grandes
• Extract Method es el
refactoring más popular para
malos olores como código
duplicado y métodos grandes
(casi el 99% de la solución es
este refactoring)

Extract Method
• El nuevo método que se ha
extraído contiene el código
seleccionado y el código
seleccionado del miembro
existente, se reemplaza por
una llamada al nuevo método.

Extract Method
Extract Method
Clases Grandes
Clases Grandes
• En la gran mayoría de las
ocasiones, una clase grande es
sinónimo de código duplicado o
que la clase está realizando más
acciones de las debidas.

• ¿cómo sabemos que una clase es


grande?
Clases Grandes
• Las clases no son grandes por el
tamaño de su código ni por su
número de elementos.

• Se debe verificar que la clase


realice solo las acciones
necesarias. Por ejemplo que no
mezcle E/S con la lógica de la
aplicación.
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 tanto los antipatrones


como los patrones de diseño, sirven de
base para no escoger malos caminos,
partiendo de documentación disponible
en lugar de simplemente la intuición.
Antipatrón BLOB

• Mejor conocido como “objeto


todopoderoso”. Se presenta
cuando una clase es muy grande
tanto en atributos y/o en
métodos.
Antipatrón BLOB

• 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
Antipatrón BLOB

• Algunos autores consideran al


Singleton (Simplicidad) un
ejemplo de un antipatrón ¿por
que?
Antipatrón BLOB
• Dificulta las pruebas de código ya
que promueve un alto
acoplamiento.

• La clase controla su propia


creación cuando esta no debe de
ser su responsabilidad.
Antipatrón BLOB
• Se recomienda utilizar el patrón
de diseño Factory para crear
objetos.

• En general su naturaleza estática


y pública no son del todo bien
vistas.
Lista de Parámetros excesiva
• El manejo de parámetros de
forma excesiva es una mala
práctica de programación ya
que implica el paso de muchos
parámetros difíciles de
recordar.

• No hay una métrica exacta


para el número de parámetros

Lista de Parámetros excesiva


• Nuestra recomendación será
manejar hasta 4 parámetros
como máximo.

• Si se supera del límite


establecido se deberá
reestructurar.

Lista de Parámetros excesiva


• Se pueden elegir otras métricas
como que el ancho del código no
rebase 80 caracteres o bien una
sola pantalla de texto.

• Se debe hacer uso de las


bondades del lenguaje como el
polimorfismo y el uso de
parámetros predeterminados.

Lista de Parámetros excesiva


• En general se debe de reestructurar
el número de parámetros por la
utilización de estructuras como
arreglos y/o objetos.

• Se recomienda utilizar refactroings


como: Replace parameters with
method e Introduce parametrs with
object

Lista de Parámetros excesiva


Características de la Envidia
• Cuando una entidad como
una clase o método están
más interesados en el
comportamiento de otra

Envidia
entidad se le denomina
envidia.

• La envidia viola el principio


de diseño de la cohesión y
eleva el acoplamiento.
• La envidia se presenta sobre
todo con los datos
(atributos).

Envidia
• La solución generalmente
implica utilizar move method
cuando todo el método es
envidioso.
• Si una sola parte de un
método o clase es envidiosa
se debe utilizar extract
method.

Envidia
• Si se presenta envidia con
muchas entidades se deberá
escoger aquella que sea la
más fuerte para colocar en
ella el método.
• Actividad: del código de la
criba se deberá reestructurar
de la siguiente forma:
Actividad

• Nótese que el método


generarCriba es muy grande
por lo que deberá
simplificarse utilizando
Extract Method de la
siguiente forma:
• Encuentre las funcionalidades y
extraiga 3 métodos:
inicializarCandidatos(max),
eliminarMultiplos(),
Actividad

obtenerCandidatosNoEliminados
();

• Haga los ajustes necesarios y


verifique que otras partes del
código se pueden reestructurar.
Sentencias Switch
Sentencias Switch
• La estructura switch causa
generalmente duplicidad en el
código.

• En general en POO debemos


utilizar polimorfismo para hacer
más legibles e intuitivos los
códigos.
Sentencias Switch
• Generalmente se aplica los
refactoring Extract Method y
Move Method aunque en otros
casos aplican refactoring más
elaborados como: Replace Type
Code with Subclasses, Replace
Type Code with State/Strategy,
Replace conditional with
Polimorphism, entre otros.
Jerarquía de Herencias
Paralelas
• Es un caso especial de
Shotgun Surgery.

• La “cirugía de escopeta” se da
cuando al modificar una clase
se tienen que modificar otras
clases en forma de cadena

Jerarquía de Herencia Múltiples


• Este mal olor se caracteriza
por que cada vez que se crea
una sublcase de una clase x,
se debe crear otra subclase de
otra clase, que generalmente
tiene el mismo prefijo que la
otra jerarquía.

Jerarquía de Herencias
• Para solucionar este mal olor
se debe utilizar refactroings
como Move Method o Move
fields para quitar las
referencias de la otra subclase
creada.

Jerarquía de Herencias
Reingeniería de Software
• La refactorización es parte
importante del proceso de
reingeniería.

• La reingeniería es una actividad


de reconstrucción, preferible de
realizar antes de que se
“derrumbe” la obra.
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.

• Es una actividad penada 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.
Ingeniería Inversa
• Existen herramientas como los
decompiladores que a partir de
un código objeto pueden obtener
código fuente.

• Todas las aplicaciones nativas se


descomponen en instrucciones
en ensamblador.
Ingeniería Inversa
• Sólo se puede obtener el código
exacto si se conoce la técnica de
generación de código objeto.

• En el caso de java existe un


decompilador básico llamado javap
o bien herramientas más
avanzadas como cavaj, MacJAD o
Java Decompiltaor, etc.
Ingeniería Inversa

• ¿Cómo se puede proteger


nuestros códigos?
Ofuscación
• La ofuscación es una técnica
avanzada de refactorización que
permite a un código mantenerle
obscuro (es decir no muy legible)
con diversos propósitos de
optimización.

• ¿No viola esto el principio de


claridad en la implantación?
Ofuscación
• La ofuscación se realiza en
muchas casos para hacer un
código ilegible, también en
muchos casos se puede reducir el
tamaño del código fuente y del
código binario realizado.
Ofuscación
Actividad
• Realizar la ofuscación del código Example
de Martin Fowler

• Refactoring de identificadores (métodos,


clases, atributos) con nombres muy
grandes y poco descriptivos.
• Agregando comentarios javadoc sin
coherencia.
• Agregando funcionalidades no utilizadas
así como código no útil.
• La ofuscación al igual que el
Téc, de Ofuscación

refactoring se puede hacer


sobre las estructuras de
datos.

• Por ejemplo en arreglos:


• Arreglos
Tec. de Ofuscación
• También se puede ofuscar
Tec. de Ofuscación

clases:
• Clases
Tec. de Ofuscacion
• Variables
Tec de Ofuscación
• Variables
Tec. de Ofuscación
• Sobre el flujo del programa
Tec. de Ofuscaciòn
• Sobre el flujo del programa
Tec. de Ofuscación
• Sobre el flujo del programa
Tec. Ofuscación

• Paralelización
• Paralelización
Tec. de Ofuscación
• Paralelización
Tec. de Ofuscación
• Ciclos
Tec. de Ofuscación
• Ciclos
Tec. de Ofuscación
Téc. De Ofuscación
• Lo más adecuado es realizar
la ofuscación sobre el código
objeto generado sin alterar
el original.

• Existen ofuscadores como


proguard, yguard que son
libres o comerciales como
Dasho o KlassMaster
Actividad
• Comparar su proyecto ofuscado con el
original a través de diff y patch

• Determina el grado de legibilidad de la


aplicación calculado a través de la
siguiente fórmula:

• Líneas negras / líneas blancas * 100


Lab
• De la página principal del sitio Web de su
profesor:
http://antares.itmorelia.edu.mx/~jcolivar/
• Realizar ofuscación de códigos para
obtener el archivo más pequeño posible.
Por ejemplo si la página es de 10KB y se
reduce en 8KB es buena la ofuscación.
Trate de eliminar líneas en blanco. La
página NO debe de cambiar. Se premiará
al que logre el menor tamaño posible con
1 PUNTO EXTRA. En caso de empate se
anula.
Campos Temporales
Campos Temporales
• Se presentan cuando existen
variables o atributos de la
clase subutilizadas.

• Generalmente están allí


debido a la utilización de
algoritmos complicados.
Campos Temporales
• Se pueden utilizar
refactorings como extract
class o Introduce Null
Objects
Encadenamiento de Mensajes
• Este mal olor es muy notorio y
se caracteriza por tener líneas
de código en las que un objeto
pide por otro y a su vez este
por otro, y así sucesivamente
logrando lo que se conoce
como cadenas de mensajes

Encadenamiento de Mensajes
• Aparentemente se reduce el
manejo de objetos temporales
pero en realidad se está
realizando mucho
acoplamiento.

• Cualquier cambio en las


relaciones internas provoca el
cambio en las subsecuentes.

Cadenas de Mensajes
• Se pueden presentar el
problema de “middle man” al
tener muchos intermediarios.

• La solución es en muchos
casos aplicar Hide Delegate,
Extract and Move Method.

Cadena de Mensajes
Clases Alternativas con
Distintos Mensajes
• Se presenta cuando se
Clases Alternativas

tienen métodos similares en


diferentes clases.

• Generalmente se debe de
renombrar el método, y en
otros casos renombrarlo.
Librerías de Clases Incompletas
Librerías de Clases Incompletas
• Las bibliotecas de clases aunque
promueven el reuso de software, sino están
bien elaboradas ocasionan muchos
problemas.

• El problema radica en que la gran mayoría


de las ocasiones, no se cuenta con el
código de la biblioteca.
Librería de Clases Incompletas
• Al no poseer el código fuente, se
vuelve complicado realizar
modificaciones.

• Se puede optar por los


refactorings de Introducir Método
Foraneo o Introducir Extesión
Local
Actividad
• Desarrollar una biblioteca en Java
que permita realizar operaciones
básicas con vectores en dos y
tres dimensiones.

• Para ello, se deberán construir


“Beans” de la implementación.
Actividad
• Una vez construida la biblioteca
deberá ser utilizada en un
proyecto donde la funcionalidad
sea utilizada por el usuario final.

• Se deberá documentar la
biblioteca con comentarios
JavaDoc.
Actividad
• Las operaciones a realizar son:

• Suma
• Resta
• Igualdad
• Multiplicación por un Escalar
• Producto punto
Suma
Resta

Producto Punto
Producto Vectorial

Producto de un vector por un


Escalar
Se multiplica el escalar por cada componente del vector

kA donde k es un escalar y A un vector se tiene:

kA= kA1x + kA2y + kA3z….


• Existen diversas clasificaciones
de malos olores. Una de las
más populares es la Mika
Mäntyla, el cual divide los
malos olores en cinco
categorías:

Otros Malos Olores


• Los que aumentan el tamaño
del código como:

• Método largo, clase larga


• Obsesión por tipos primitivos:
aquí no se utilizan ADT cuando
el tipo de dato lo requiere.
Ejemplo: tipo de dato teléfono

1. Infladores
• Lista de parámetros larga

• Grupos de datos (dataclump):


se presenta cuando se utilizan
muchos datos aislados que
podrían simplificarse utilizando
un objeto o estructura para
ello.

1. Infladores
• Sentencias switch
• Campo temporal
• Clases alternas con distintas
interfaces
• Rechazo del legado: cuando
una clase se reusa a utilizar su
herencia.

2. Abusadores de POO
• Cambio divergente: cuando se
implementan en las clases
funcionalidades diferentes al
contexto de la clase

• Cirugía de escopeta
• Jerarquía de herencias
paralelas

3. Impedidores de cambio
• Clases holgazanas
• Clases de datos: cuando una
clase sólo almacena datos
pero no tiene métodos para
acceder a ellos

• Código duplicado

4. Los prescindibles
• Código muerto: código legado
que ya no se utiliza en la
versión actual del código.

• Generalización especulativa:
sucede cuando un código
intenta solucionar problemas
más allá de sus alcances
originales.

4. Los prescindibles
• Alertan sobre alto
acoplamiento de
componentes.

• Característica de la envidia
• Cadenas de mensajes
• Intermediarios

5. Los emparejadores
• Intimidad inapropiada: ocurre
cuando dos clases se conocen
demasiado y se usan con
demasiada confianza, el
problema se presenta cuando
esa relación en términos de
POO es inapropiada.

5. Los emparejadores
• Necesito de un software que
Hisoria de Usuario

permita llevar acabo el


seguimiento de mis
pacientes.

• La secretaria debe poder


agendar una cita y tener los
datos de contacto del
paciente (teléfono, domicilio,
etc.)
• Por mi parte, debo de poder
Historia de Usuario

realizar una cita clínica y


poder imprimir una receta
médica.

• Las citas clínicas se van


almacenando en un
expediente electrónico para
posteriormente visualizarlo
• Interacción 1: funcionalidad
de agendar citas
Laboratorio 5

• Interacción 2: funcionalidad
de captura de historia clínica
y expedición de recetas

• Interacción 3: funcionalidad
de consultar expedientes
clínicos.
• Programar la interacción que
les corresponda.

• Aspectos de diseño de
Lab 5

interfaces de usuarios salen


en segundo plano.
• Los malos olores dependen
del autor aunque son

Conclusiones
consistentes.

• Por ejemplo Jeff Bay en su


artículo Object Calisthenics
sugiere 9 reglas a seguir
para construir software de
calidad:
• 1.Usa solo un nivel de indentación
por método

Conclusiones
• 2.No uses el “else” dentro de una
condicional

• 3.Usa Wrappers para los tipos


primitivos y las cadenas

• 4.Solo usa un punto por línea


• 5.No abrevies

Conclusiones
• 6.Mantén las entidades
pequeñas

• 7.No utilices una clase


que tenga más de 2
variables de instancia.
• 8.Una clase que contenga
una colección no debe

Conclusiones
contener otras variables
de instancia

• 9.No use propiedades, ni


getters ni setters
• ¿qué se tendría que hacer en el
programa si la biblioteca utilizada
realiza cálculos erróneos (por
ejemplo manejar números
complejos) y no se dispone del
código fuente para modificarlo?

• Identificar mal olor

Actividad
• Librerías de Clases Incompletas

• Solución: introducir método


foráneo o introducir extensión
local.

• Se puede utilizar el patrón de


diseño adapatador

Actividad
Dudas

Vous aimerez peut-être aussi