escuela técnica superior de ingenieríainformática
Tema 3 -
Principios de diseño
Ingeniería del Software de Gestión II Grupo de Ingeniería del Software
♦ Conocemos
♦ La importancia de hacer desarrollos mantenibles. ♦ El concepto y la necesidad de llevar a cabo el diseño
de un proyecto software. ♦ Queremos ser capaces de
♦ Describir los principios fundamentales de diseño ♦ Realizar un diseño mantenible por medio de la
aplicación sistemática de principios de diseño. ♦ Evaluar la calidad de un diseño en función de
principios evaluativos de diseño.
♦ Son aplicables a todos los niveles del diseño desde la arquitectura a la microarquitectura. ♦ Todos están muy relacionados entre si.
♦ Podemos dividir en:
♦ Principios generales de la ingeniería del software ♦ Principios específicos de diseño
♦ Principios generales de la Ingeniería
del Software
♦ Principios específicos del diseño
♦ Diseño guiado por responsabilidades
♦ Reutilizando conocimiento
♦ Conclusiones
Principios generales de la
ingeniería del software
Principios de Ing. Soft. Para sistemas software Complejos
Definición
Abstracción Omitir detalles no relevantes
Descomposición Divide y vencerás
Composición Unir partes para obtener un resultado mayor
Automatización Automatizar el proceso de desarrollo de
software
Reutilización Reutilizar desde requisitos a código
Principios generales de la
ingeniería del software
♦ Están surgiendo numerosas técnicas y tecnologías con el objetivo de construir software más complejo
Principios Técnicas y
Técnologias
Abstracción BDD, AOSE, Autonomic Computing, MDA
Descomposición Aspectos
Composición Componentes, Servicios Web
Automatización MDA
♦ Principios generales de la Ingeniería del
Software
♦ Principios específicos del diseño
♦ Diseño guiado por responsabilidades
♦ Reutilizando conocimiento
♦ Conclusiones
Acoplamiento
Cohesión
♦ Medida cualitativa del grado en el que un módulo está conectado a otros y al mundo exterior.
Acoplamiento
Acoplamiento
Acoplamiento
Cohesión
Cohesión
♦ Medida cualitativa del grado de relación entre los elementos de un módulo
Cohesión
♦ Principio evaluativo
“Un elemento es altamente cohesivo si todos
sus elementos trabajan juntos para
proporcionar algún comportamiento bien delimitado”
Nuestro enemigo:
♦ Punto de variación ♦ Punto de evolución
Nuestro objetivo
Lograr que los
cambios
involucren la
menor cantidad de
código posible y
estén lo más
acotados posible.
Variaciones protegidas
Intentar ocultar/proteger de los cambios al resto del sistema
Variaciones protegidas
♦ “…proponemos en lugar de eso que uno comience con una lista de decisiones de diseño difíciles o con altas probabilidades de cambio. Cada módulo se diseña entonces para ocultar dichas decisiones a otros…”
“On the criteria to be used in
decomposing systems into modules”,
Encapsulación de lo que varía
Principio de inversión de la dependencia Principio de separación de la interfaz Uso de datos externos
Ocultación de la estructura (Ley de Demeter)
Variaciones protegidas
Encapsulación de lo que varía
Principio de inversión de la dependencia Principio de separación de la interfaz Uso de datos externos
Ocultación de la estructura (Ley de Demeter)
Variaciones protegidas
¿Cómo se hace esto?
Dinero cantidad= venta.getPago().getCantidadEntregada ():
//Clase acoplada con Venta y con Pago
Dinero cantidad= venta.getCantidadEntregadaEnPago(); //Clase acoplada sólo con Venta
Principio abierto / cerrado Evitar código duplicado
Principio de sustitución de Liskov
Variaciones protegidas (cont.)
Principio abierto / cerrado Evitar código duplicado
Principio de sustitución de Liskov
Variaciones protegidas (cont.)
¿Cómo se hace esto?
public class Rectangle {
protected float height, width; public void setHeight (float h) { height= h;
}
public void setWidth (float w){ width= w;
}
public float getHeight(){ return height;
}
public float getWidth(){ return width;
} }
public class Square
extends Rectangle {
public void setHeight (float h) {
super.setHeight(h); super.setWidth(h); }
public void setWidth (float w) {
super.setHeight(w); super.setWidth(w); }
}
public class LiskovTest { public void run() {
Rectangle r= new Rectangle(); test(r);
Square s= new Square(); test(s); } void test(Rectangle r){ r.setHeight(5); r.setWidth(4); if (r.getHeight()*r.getWidth()==20) System.out.println(“Ok”); else System.out.println(“Not ok”); } }
♦ El coste de diseñar la protección de un punto de
variación o de evolución debe ser inferior a rehacer un diseño simple
♦ Principios generales de la Ingeniería del
Software
♦ Principios específicos del diseño
♦ Diseño guiado por responsabilidades
♦ Reutilizando conocimiento
♦ Conclusiones
Diseño guiado por
responsabilidades
♦ ¿Cómo asigno responsabilidades siguiendo esos principios de diseño?
♦ Craig Larman propone un conjunto de guías a los que ha denominado GRASP (General
Experto en
Información
Creador
Invención
Pura
Indirección
Experto en
Información
Creador
Invención
Pura
Indirección
Experto en Información
Problema: ¿cómo empiezo a asignar
responsabilidades?
Solución: Asigne una responsabilidad al experto en
información (a quien tiene la información
necesaria para llevar a cabo la responsabilidad)
Ejemplo: ¿quién debe ser el responsable de conocer
Experto en información
♦ Se distribuye el
comportamiento entre las clases que contienen la información requerida (Mayor cohesión) ♦ Se mantiene el encapsulamiento de la información (Menor acoplamiento) ♦ En ocasiones su aplicación puede aumentar el acoplamiento y reducir la cohesión (Ej. ¿quién
debería de almacenar una Venta en la BBDD?)
Experto en
Información
Creador
Invención
Pura
Indirección
Creador
Problema: ¿Quién debe ser el responsable de la
creación de una nueva instancia de una clase?
Solución: Aquella que vaya a usar la instancia de
la clase más estrechamente.
Ejemplo: ¿Quién debería ser responsable de la
Creador
♦ Favorece el bajo acoplamiento
♦ En ocasiones la creación posee una complejidad significativa resultando más conveniente delegar esta responsabilidad en una clase diseñada a tal efecto
Experto en
Información
Creador
Invención
Pura
Indirección
Problema: ¿Cómo proceder cuando las soluciones
encontradas comprometen la cohesión?
Solución: Asigne un conjunto cohesivo de
responsabilidades a una clase artificial (no representa ningún concepto del dominio del problema)
Ejemplo: Definir una clase (PersistentStore) cuya
única responsabilidad es almacenar objetos de cualquier tipo en la base de datos.
Invención pura
♦ Las invenciones puras suelen ser muy cohesivas y reutilizables
♦ Demasiadas invenciones puras puede derivar en clases excesivamente simples que necesitan mucha información de otras para poder realizar las responsabilidades (Alto acoplamiento).
Experto en
Información
Creador
Invención
Pura
Indirección
Problema: ¿Dónde asignar responsabilidades para evitar/
reducir el acoplamiento directo entre elementos y mejorar la reutilización?
Solución: Asigne la responsabilidad a un objeto que medie entre los elementos.
Ejemplo: Adaptación del cálculo de impuestos (IVA) para distintos países (Sale es ahora más reutilizable).
Indirección
♦ Disminuyen el acoplamiento
♦ Demasiadas indirecciones puede hacer al diseño difícil de entender y depurar.
♦ Principios generales de la Ingeniería del
Software
♦ Principios específicos del diseño
♦ Diseño guiado por responsabilidades
♦ Reutilizando conocimiento
♦ Conclusiones
Idioms Refactorizaciones Antipatrones Patrones de diseño
Reutilizando conocimiento
Código IdeasTu cerebro El código que escribes
Patrones de diseño
Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno. También describe el
núcleo de la solución al problema, de forma que puede utilizarse un millón de veces sin hacer dos
Antipatrones
♦ Se aprende de los errores más que de los aciertos ♦ Recetas que no deben emplearse
♦ Ejemplos
♦ The blob ♦ Poltergeists ♦ Cut and paste ♦ Spaguetti code ♦ …
Refactorización
♦ “Es el proceso de cambiar un sistema de
software de tal forma que no se altere el
comportamiento externo de su código (diseño) y aún así se mejore su estructura interna”
Idioms
♦ Una forma característica de utilizar un lenguaje de programación.
♦ Describen soluciones a problemas de
implementación de un determinado lenguaje de programación.
♦ Iteradores en Java
♦ Métodos get y set en Java
♦ Principios generales de la Ingeniería del
Software
♦ Principios específicos del diseño
♦ Diseño guiado por responsabilidades
♦ Reutilizando conocimiento
♦ Conclusiones
♦ Nuestro enemigo es el CAMBIO y debemos protegernos contra él.
♦ Nuestro objetivo debe ser conseguir diseños poco acoplados y altamente cohesivos.
♦ Tenemos a nuestra disposición una batería de principios de diseño, patrones y
refactorizaciones para diseñar protegiéndonos del cambio.
♦ Describir los principios fundamentales de diseño vistos en esta lección.
♦ Realizar un diseño mantenible por medio de la aplicación sistemática de principios de diseño. ♦ Evaluar la calidad de un diseño en función de
los principios evaluativos de diseño (cohesión y acoplamiento).
Bibliografía
♦ Basica (de referencia):
♦ “Ingeniería del Software. Un enfoque práctico”. Roger S.
Pressman. Mc Graw Hill (6ª ed.) [Capítulo 9]
♦ “UML y patrones”. Craig Larman. Prentice-Hall (2ª ed.)
[Capítulo 17, para los GRASP]
♦ De apoyo:
♦ “Ingeniería del Software”. Ian Sommerville. Pearson Addison
Wesley (7ª ed.) [Capítulo 11]
♦ “Head First Design Patterns”. Eric Freeman y Elisabeth Freeman. O’Reilly, 2004. [Buscar en el índice Object Oriented Design Principles]