Publicado el 14 de Enero del 2017
848 visualizaciones desde el 14 de Enero del 2017
210,3 KB
15 paginas
Creado hace 14a (26/10/2010)
Patrones de diseño
Reuso del desarrollo a nivel arquitectural
M. Telleria, L. Barros, J.M. Drake
1
Patrones de diseño
Soluciones de diseño que son válidas en distintos contextos y
que han sido aplicadas con éxito en otras ocasiones.
● Se debe haber comprobado su efectividad resolviendo problemas
similares en ocasiones anteriores.
● Deben ser reusables: se puede aplicar a diferentes problemas de
diseño en distintas circunstancias.
● Estamos a nivel de UML
● Término acuñado por Christophe Alexander en arquitectura
(de edificios) y popularizado en informática por el Gang of Four:
● Erich Gamma
● Richard Helm
● Ralph Johnson
● John Vlissides
famosos por el libro “Design Patterns: Elements of Reusable Object-
Oriented Software (1996)”
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
2
Libro del Gang Of Four (GOF book)
Fuente: http://en.wikipedia.org/wiki/Design_Patterns
● Libro de ingeniería de software muy
influyente publicado en 1995.
● Neutral respecto al lenguaje. Asume
sólo que es orientado a objetos
● Consejos que da:
● Composición frente a herencia.
● Centrarse en interfaces frente a
implementación.
● Uso de tipos genéricos.
● Presenta patrones diversos:
Creación de objetos: Abstract Factory, Builder...
● Estructura: Adapter, Facade...
● Comportamiento: Iterator, Interpreter, State...
Patrones de diseño | ProConDis
M. Telleria, L. Barros, J.M. Drake
3
Ventajas de los patrones de diseño
Ayudan a “arrancar” en el diseño de un programa complejo.
● Dan una descomposición de objetos inicial “bien pensada”.
● Pensados para que el programa sea escalable y fácil de mantener.
● Otra gente los ha usado y les ha ido bien.
● Ayudan a reutilizar técnicas.
● Mucha gente los conoce y ya sabe como aplicarlos.
● Estamos en un alto nivel de abstracción.
● El diseño se puede aplicar a diferentes situaciones.
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
4
Ejemplo: Maquina de estado
Tenemos la siguiente máquina de estado
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
5
Objetivo: Ofrecer una interfaz
public static void main(String[] args) {
public static void main(String[] args) {
PuertaGarageInt puerta = new PuertaGarage();
PuertaGarageInt puerta = new PuertaGarage();
puerta.pulsaBoton();
puerta.pulsaBoton();
puerta.sensorAbierto();
puerta.sensorAbierto();
puerta.pulsaBoton();
puerta.pulsaBoton();
puerta.sensorPaso();
puerta.sensorPaso();
puerta.sensorAbierto();
puerta.sensorAbierto();
puerta.pulsaBoton();
puerta.pulsaBoton();
puerta.sensorCerrado();
puerta.sensorCerrado();
}}
Compuesta por los eventos externos.
● Con datos estrictamente funcionales
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
6
Todos sabemos implementar una m.d.e.
Implementación típica (seguramente la primera que se nos
ocurre)
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
7
Implementacion clásica (codigo java)
public void pulsaBoton(){
public void pulsaBoton(){
switch(currentState)
switch(currentState)
{{
case CERRADO:
case CERRADO:
exitAction();
exitAction();
currentState=GarageState.ABRIENDO;
currentState=GarageState.ABRIENDO;
entryAction();
entryAction();
break;
break;
case ABRIENDO:
case ABRIENDO:
exitAction();
exitAction();
currentState=GarageState.CERRANDO;
currentState=GarageState.CERRANDO;
entryAction();
entryAction();
break;
break;
case ABIERTO:
case ABIERTO:
exitAction();
exitAction();
currentState=GarageState.CERRANDO;
currentState=GarageState.CERRANDO;
entryAction();
entryAction();
break;
break;
case CERRANDO:
case CERRANDO:
exitAction();
exitAction();
currentState=GarageState.ABRIENDO;
currentState=GarageState.ABRIENDO;
entryAction();
entryAction();
break;
break;
}}
}}
private void entryAction()
private void entryAction()
{{
switch(currentState)
switch(currentState)
{{
case ABRIENDO:
case ABRIENDO:
motorUp();
motorUp();
break;
break;
case CERRANDO:
case CERRANDO:
motorDown();
motorDown();
break;
break;
default: {};
default: {};
}}
}}
}}
private void exitAction()
private void exitAction()
{{
switch(currentState){
switch(currentState){
case ABRIENDO:
case ABRIENDO:
motorStop();
motorStop();
break;
break;
case CERRANDO:
case CERRANDO:
motorStop();
motorStop();
break;
break;
default: {};
default: {};
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
8
Problemas de la implementación clásica
Dos bloques switch anidados:
● Para el estado actual
● Para el evento
● Añadir un estado significa modificar los 2 bloques switch
● Y no equivocarse!!.
● El código está articulado en función de los eventos
● Pero el pensamiento del diseñador está en función de los estados.
● No hay reuso o sobrecarga en función de los estados
● No se puede reusar acciones comunes entre los diferentes case del
switch.
● No se puede definir atributos específicos a cada estado.
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
9
Patrón de máquina de estado
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
10
Claves del funcionamiento
La clase PuertaGarageEstado fuerza el polimorfismo.
● En realidad la clase contexto (PuertaGarageContext) siempre tendrá una
referencia a los objetos de las subclases estado una vez llama al arranca().
● No puede ser abstracta porque es necesario instanciarla.
● Los abtributos estado (estadoCerrado … estadoAbriendo) han de
ser estáticos.
● De forma que cuando la clase contexto ejecute los métodos evento
(pulsaBoton(), etc) los ejecute siempre sobre los mismos objetos (y no atributos
de esos objetos).
● La funcionalidad del método arranca() no se puede incluir en el
constructor de PuertaGarageEstado()
● De lo contrario aparecerían problemas de recurrencia infinita.
● La clase contexto libera al programa usuario de obligaciones ligadas al
patrón.
● Llamar al método arranca() y recoger el resultado de los métodos evento y
sobreescribirlo en la referencia al estado.
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
11
Traducción a código (I): Clase Context
public class PuertaGarageContexto implements PuertaGarageInterface{
public class PuertaGarageContexto implements PuertaGarageInterface{
private PuertaGarageEstadosPattern estado_actual;
private PuertaGarageEstadosPattern estado_actual;
public PuertaGarageContexto()
public PuertaGarageContexto()
{{
estado_actual = new PuertaGarageEstadosPattern();
estado_actual = new PuertaGarageEstadosPattern();
estado_actual = estado_actual.arranca();
estado_actual = estado_actual.arranca();
public void pulsaBoton()
public void pulsaBoton()
{{
estado_actual = estado_actual.pulsaBoton();
estado_actual = estado_actual.pulsaBoton();
}}
}}
}}
}}
}}
}}
public void sensorAbierto()
public void sensorAbierto()
{{
estado_actual = estado_actual.sensorAbierto();
estado_actual = estado_actual.sensorAbierto();
public void sensorCerrado()
public void sensorCerrado()
{{
estado_actual = estado_actual.sensorCerrado();
estado_actual = estado_actual.sensorCerrado();
public void sensorPaso()
public void sensorPaso()
{{
estado_actual = estado_actual.sensorPaso();
estado_actual = estado_actual.sensorPaso();
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
12
Traducción a código (II): Clase Estados
public class PuertaGarageEstadosPattern {
public class PuertaGarageEstadosPattern {
private static Cerrado estadoCerrado;
private static Cerrado estadoCerrado;
private static Abriendo estadoAbriendo;
private static Abriendo estadoAbriendo;
private static Abierto estadoAbierto;
private static Abierto estadoAbierto;
private static Cerrando estadoCerrando;
private static Cerrando estadoCerrando;
protected void entry() { }
protected void entry() { }
protected void exit() { }
protected void exit() { }
public PuertaGarageEstadosPattern arranca()
public PuertaGarageEstadosPattern arranca()
{{
estadoCerrado = new Cerrado();
estadoCerrado = new Cerrado();
estadoAbierto = new Abierto();
estadoAbierto = new Abierto();
estadoAbriendo = new Abriendo();
estadoAbriendo = new Abriendo();
estadoCerrando = new Cerrando();
estadoCerrando = new Cerrando();
estadoCerrado.entry();
estadoCerrado.entry();
return estadoCerrado;
return estadoCerrado;
}}
// Eventos
// Eventos
public PuertaGarageEstadosPattern pulsaBoton() { return this; }
public PuertaGarageEstadosPattern pulsaBoton() { return this; }
public PuertaGarageEstadosPattern sensorAbierto() { return this; }
public PuertaGarageEstadosPattern sensorAbierto() { return this; }
public PuertaGarageEstadosPattern sensorCerrado() { return this; }
public PuertaGarageEstadosPattern sensorCerrado() { return this; }
public PuertaGarageEstadosPattern sensorPaso() { return this; }
public PuertaGarageEstadosPattern sensorPaso() { return this; }
// Acciones
// Acciones
private void motorUp() {
private void motorUp() {
System.out.println("Motor Up activado");
System.out.println("Motor Up activado");
}}
private void motorDown() {
private void motorDown() {
}}
private void motorStop() {
private void motorStop() {
System.out.println("Motor Down activado");
System.out.println("Motor Down activado");
System.out.println("Motor Stop activado");
System.out.println("Motor Stop activado");
}}
// SUBCLASSES AQUI
// SUBCLASSES AQUI
M. Telleria, L. Barros, J.M. Drake
Patrones de diseño | ProConDis
13
Traducción a código (III): Sub-clases estados
private class Abriendo extends PuertaGarageEstadosPattern
private class Abriendo extends PuertaGarageEstadosPattern
{{
protected void entry()
protected void entry()
{{
super.entry();
super.entry();
motorUp();
motorUp();
}}
public PuertaGarageEstadosPattern pulsaBoton() {
public PuertaGarageEstadosPattern pulsaBoton() {
this.exit();
this.exit();
estadoCerrando.entry();
estadoCerrando.entry();
return estadoCerrando;
return estadoCerrando;
}}
public PuertaGarageEstadosPattern sensorA
Comentarios de: Patrones de diseño - Reuso del desarrollo a nivel arquitectural (0)
No hay comentarios