Este artigo precisa de máis fontes ou referencias que aparezan nunha publicación acreditada que poidan verificar o seu contido, como libros ou outras publicacións especializadas no tema. Por favor, axude mellorando este artigo. (Desde maio de 2012.) |
Este artigo ou sección precisa dunha revisión do formato que siga o libro de estilo da Galipedia. Pode axudar a mellorar este artigo e outros en condicións semellantes. |
Este artigo ou sección precisa dunha revisión ortográfica e/ou de gramática (recurso útil: corrector ortográfico en liña de galego). Podes axudarte do revisor ortográfico, activándoo en: Preferencias → Trebellos → Navegación → Ortografía: Activar o revisor ortográfico. Colabora connosco neste artigo e noutros en condicións semellantes para que a Galipedia mellore e medre. |
O padrón Estratexia (Strategy) é un padrón de deseño, clasificado como de comportamento de obxectos. O seu obxectivo é a definición dunha familia de algoritmos, encapsulándoos e facéndoos intercambiables. Deste xeito, ditos algoritmos poderán variar de forma independente ás clases que os usan e ser reutilizados.
Imaxinemos o caso da división dun texto en liñas, para o cal existen múltiples algoritmos. Se optásemos por un enfoque tradicional, codificando estes en cada clase cliente que os usase:
A alternativa que o padrón Estratexia propón a esta situación é a definición de clases que encapsulen os diferentes algoritmos de partición de liñas. Desta forma, os clientes que necesiten dividir un texto non deberán implementar o código de cada algoritmo, pois este estará encapsulado nunha clase estratexia na que o cliente, a través dun contexto intermedio, delegará a responsabilidade de dividir o texto.
É axeitado o uso do padrón Estratexia nas seguintes situacións:
No escenario definido por este padrón atopamos dúas colaboracións principais entre as clases participantes. A primeira delas é a interacción entre Contexto e Estratexia para facer chegar a esta a información necesaria para a execución do algoritmo. Neste punto, atopamos dúas posibles alternativas:
Estas opcións serán analizadas con máis detalle no apartado de Implementación. A segunda colaboración fai referencia ós clientes. Estes, inicialmente, crearán a EstratexiaConcreta coa que configurarán o Contexto (pode facerse a través dalgún padrón de creación), e, despois disto, unicamente terán que interactuar con el.
A aplicación do padrón Estratexia proporciona as seguintes vantaxes:
Da mesma forma, podemos atopar os seguintes inconvenientes á hora de de empregar este padrón:
Como xa se comentou, na definición da interface entre a estratexia e o contexto, existen diferentes alternativas:
O uso dunha ou outra opción estará determinado polo algoritmo concreto e as necesidades do sistema.
Outra cuestión de implementación a tratar é permitir o emprego opcional das estratexias. Deste xeito os clientes poderían non coñecer as estratexias concretas cando non fose necesario. O Contexto simplemente tería que comprobar se ten un obxecto estratexia asociado e, se non é así, executar un comportamento por defecto. Este comportamento podería ser implementado incluso como unha estratexia, eliminando así a comprobación no Contexto (verase no exemplo de implementación).
A continuación preséntase un exemplo de implementación do padrón estratexia para o problema da ordenación dun vector. En relación co comentado anteriormente, unha posible optimización neste caso sería o uso do padrón Singleton para os obxectos estratexia, xa que estes son completamente independientes do Contexto e soamente coa información pasada como parámetro (o vector e o tamaño deste) poden realizar a ordenación; é dicir non almacenan estado interno referente ó contexto. Evidentemente, a vantaxe disto sería a redución do número de obxectos no sistema ante o uso das estratexias por parte de diferentes obxectos Contexto.
public class Cliente {
public static void main(String argv[]) {
Contexto c = new Contexto(7);
System.out.println("Sen Ordenamento: " + c.visualizarVector());
c.establecerOrdenamento(new OrdenamentoSeleccion());
System.out.println("Ordenamento Burbulla: " + c.visualizarVector());
}
}
public class Contexto {
private int _vector[];
private int _tamano;
private Ordenamento _ordenamento;
public Contexto(int tamano) {
_tamano = tamano;
_vector = new int[_tamano];
_ordenamento = new SenOrdenamento();
inicializar();
}
// Este método inicializa _vector con valores no rango (-100,100)
public void inicializar() {
java.util.Random generador = new java.util.Random();
for (int i = 0; i < _tamano; i++)
_vector[i] = generador.nextInt() % 100;
}
// Este método permítenos cambiar a estratexia de ordenamento
public void establecerOrdenamento(Ordenamento o) {
_ordenamento = o;
}
// Úsase a estratexia para ordenar o vector antes de convertilo nun String
public String visualizarVector() {
_ordenamento.ordenar(_vector, _tamano);
int i;
String s = "";
for (i = 0; i < _tamano; i++) {
s += _vector[i] + " ";
}
return s;
}
}
public abstract class Ordenamento {
public abstract void ordenar(int vector[], int tamano);
}
public class OrdenamentoBurbulla extends Ordenamento {
public void ordenar(int vector[], int tamano) {
int i, j, temp;
for (i = 1; i < tamano; i++)
for (j = 0; j < tamano - 1; j++)
if (vector[j] > vector[j + 1]) {
temp = vector[j];
vector[j] = vector[j + 1];
vector[j + 1] = temp;
}
}
}
public class OrdenamentoInsercion extends Ordenamento {
public void ordenar(int vector[], int tamano) {
int i, temp, j;
for (i = 1; i < tamano; i++) {
temp = vector[i];
for (j = i - 1; (j >= 0) && (vector[j] > temp); j--)
vector[j + 1] = vector[j];
vector[j + 1] = temp;
}
}
}
public class OrdenamentoSeleccion extends Ordenamento {
public void ordenar(int vector[], int tamano) {
int i, j, p, temp;
int lim = tamano - 1;
for (i = 0; i < (tamano - 1); i++) {
p = i;
for (j = i + 1; j <= lim; j++) {
if (vector[j] < vector[p])
p = j;
}
temp = vector[p];
vector[p] = vector[i];
vector[i] = temp;
}
}
}
public class SenOrdenamento extends Ordenamento {
public void ordenar(int vector[], int tamano) {
// Método baleiro. O vector queda como estaba.
}
}