Descargar 128,0 kb - U

Anuncio
Modelar usando patrones
Problema: Se quiere desarrollar un editor de texto que posea
comandos tales como insertar una línea, borrar una línea, insertar
un caracter, borrar un caracter, etc. El editor debe contar con un
mecanismo para hacer undo y redo cuyos requerimientos son los
siguientes:
1. Mecanismo diseñado aplicable en una gran variedad de
aplicaciones

Debe ser independiente de la aplicación
2. Mecanismo no requiere rediseño al agregar un nuevo
comando

Evitar UNDO/REDO tratados como comandos:
if ultimo__comando == INSERTAR
UNDO ultima inserción
else if ultimo__comando == BORRAR
UNDO ultima acción de borrar
Modelar usando patrones
3. Mecanismo hace un uso razonable del espacio

Almacenar sólo información necesaria

Ejemplo: BORRAR una línea almacena sólo el número línea y texto
4. Mecanismo aplicable una gran cantidad de

Permitir un mecanismo flexible
Programación orientada a objetos
veces
Modelar usando patrones
Abstracción clave: Comando
Operaciones de Comando: execute (redo) y undo
“Los comandos son vistos como objetos bien equipados
capaces que contienen la información necesaria para ejecutarse
y deshacerse a si mismos”
Programación orientada a objetos
Modelar usando patrones
Comenzado con Un nivel de Undo: (en pseudo- java)
boolean modoUndo= false; Comando comandoActual=null;
// ....
if( pedido es un pedido normal){
crear pedido adecuado y almacenarlo en comandoActual
comandoActual.execute();
modoUndo = false;
}
else if( pedido es Undo){
if( modoUndo ){
comandoActual.execute(); //Redo
else{
comandoActual.undo();
modoUndo = true;
}
}
Programación orientada a objetos
Modelar usando patrones
¿Qué hemos logrado?
ninguna operación es dependiente de la aplicación.
¿Cómo crear el pedido adecuado?
if (pedido == InsertarLinea){
comandoActual = new InsertarLinea(...);
... }
else if( pedido == BorrarLinea){
comandoActual = new BorrarLinea();
... }
else ...
Comentarios:

Una parte de la implementación debe conocer la lista exhaustiva

Importante evitar que if-else de este tipo existan más de una vez
Programación orientada a objetos
Modelar usando patrones

Qué patrón podemos usar?
Factory method parametrizado (primera versión)

class CreadorDeComandos{
public CreadorDeComandos(){}
public Comando crear( int id ){
if( id == InsertarLinea) return new InsertarLinea();
if( id == BorrarLinea) retunr new BorrarLinea();
....
return null;
}
}
Programación orientada a objetos
Modelar usando patrones
Segunda solución: (múltiples Undo y Redo)
 List<Comando> listaComandos = new ArrayList<Comando>();
 Para al recorrido usar patrón iterador:
Iterator iterador = listaComandos.iterator();
Métodos: hasPrevious(), hasNext(), next(), previous()
/* Implementación de Undo
if( iterador.hasPrevious(){
comandoActual = iterador.previous()
comandoActual.undo()
else error()
}
Programación orientada a objetos
Modelar usando patrones

/* Implementación de Redo
if( !iterador.hasNext()){
comandoActual = iterador.next()
comandoActual.execute();
else error();
}
Programación orientada a objetos
Modelar usando patrones
 /* Ejecución de comando normal
// borrar todos los comandos alos que se le aplico Undo
while( iterador.hasNext() ){
iterator.remove();
}
iterador.add(comandoActual);
comandoActual.execute();
Programación orientada a objetos
Modelar usando patrones
¿Cómo crear un pedido sin if-else?
Definir una constante por cada comando (Insertar- Linea = 0,
BorrarLinea = 1, ...)
 Comando*templateDeComandos[NumeroMaxComandos];
 templateDeComandos[InsertarLinea] = new InsertarLinea();
 templateDeComandos[BorrarLinea] = new BorrarLinea();
 ...

Donde?
Programación orientada a objetos
Modelar usando patrones
class CreadorDeComandos{
private Comando[] templatesDeComandos;
private int numeroComandos;
private int metodoHashing(int id){ ....}
public CreadorDeComandos(){
// inicializar de un archivo o de otra forma
templateDeComandos = new Comando[NumeroMaximoComandos];
templateDeComandos[InsertarLinea] = new InsertaLinea();
templateDeComandos[BorrarLinea] = new BorrarLinea()
....
numeroComandos = ??;
}
public Comando crear( int id ){
return templateDeComandos[metodoHashing(id)].clone();
}
}
Programación orientada a objetos
Modelar usando patrones
¿Cómo crear el comando actual? Si la interacción es a través
del teclado interactuando con un usuario
CreadorDeComandos creadorDeComandos = new CreadorDeComandos();
....
while( pedido != Salir){
if( pedido == Undo ){ .... // slide 7}
elseif( pedido == Redo){ ... // slide 8 }
else{
comandoActual=creadorDeComandos.crear(pedido);
comandoActual.askUser(); //solicitar informacion al usuario
while( iterador.hasNext() ){
iterator.remove();
}
iterador.add(comandoActual);
comandoActual.execute();
}
}
Programación orientada a objetos
Modelar usando patrones


Otros patrones usados:
prototype y command
Nota: dentro de el método execute se debe llamar un método
llamado askUser, para solicitar la información del comando que se
va a ejecutar. Por ejemplo, en el caso de InsertarLinea se debe
obtener el número de línea y el texto a insertar. Se recomienda el
método askUser sea implementado como un método protected
dentro de los comandos que lo necesitan.
Programación orientada a objetos
Descargar