Patrones de diseño. Strategy

Introducción

El patrón strategy (estrategia) esta orientado a resolver situaciones en las que nos encontramos con un problema base pero existen diversas estrategias para abordar el problema. En este sentido nuestro problema define un interface que será (o podrá ser) implementado de diversas formas.

Problema

El patrón Strategy aborda problemas que pueden (o se prevee que puedan) ser implementados o afrontados de distintas formas y cuyo interfaz esta bien definido y es común para dichas formas, pudiendo ser cualquiera de ellas valida o más desable en determinadas situaciones y permitiendo el cambio entre las distintas estrategias en tiempo de ejecución.

Estructura

main.php?g2_view=core.DownloadItem&g2_itemId=825&g2_serialNumber=1

Código de ejemplo

Un ejemplo básico (y sencillo) consiste en la implementación de un algoritmo de busqueda determinado. De esta forma tenemos un interfaz claro (una función que recibe una lista y la ordena) pero con distintas formas de realizar la ordenación, diversos algoritmos, ordenación por burbuja, merge sort, quick sort... etc. (Obviamente en el ejemplo no están implementados cada uno de los algoritmos de ordenado)

namespace StrategyPatterns
{
  // Definición del interfaz
  public interface ISort
  {
    void Sort(List<string> list)
  }

  // Implementación QuickSort
  public class CQuickSorter : ISort
  {
    void Sort(List<string> list)
    {
      // Implementación Quick Sort
    }
  }

  // Implementación Burbuja
  public class CBurbujaSorter
  {
    void Sort(List<string> list)
    {
      // Implementación en Burbuja
    }
  }

  // Implementación MergeSort
  public class CMergeSort
  {
    void Sort(List<string> list)
    {
      // Implementación MergeSort
    }
  }

  public class Contexto
  {
    private ISort sorter;

    public Contexto(ISort sorter)
    {
      this.sorter = sorter;
    }

    public ISort Sorter
    {
      get{return sorter;)
    }
  }

  public class MainClass
  {
    static void Main()
    {
       List<string> myList = new List<string>();

       myList.Add("Hola mundo");
       myList.Add("Otro item");
       myList.Add("Tercer item");

       Contexto cn = new Contexto(new CQuickSorter());
       cn.Sorter.Sort(myList); // Ordenado con quicksort
       myList.Add("Uno más para el merge sort");
       cn = new Contexto(new CMergeSort());
       cn.Sorter.Sort(myList); // Ordenado con mergesort
    }
  }
}

Ejemplos reales

.NET Sytem.Data

En .NET se aplica este patrón con bastante frecuencia. Uno de los ejemplos más concretos se corresponde con la infraestructura de acceso a base de datos en la cual existen una serie de interfaces (IDbConnection, IDBCommand...) que reciben una implementación concreta según la base de datos (estrategia) que se desee implementar (OracleConnection, OracleCommand...)

Lectores de datos

Otra aplicación habitual de un patron strategy se da en los lectores de datos. El interfaz vuelve a estar bien definido, necesitamos un determinado flujo de datos (un stream de bytes, una cadena de texto claro, una cadena xml) pero el origen de ese determinado flujo puede variar. De esta forma existen diversos interfaces (IStreamReader, IXMLReader, ITextReader) así como una serie de implementadores de dichos interfaces, TCPReader, FileReader... etc.

8
Average: 8 (3 votes)
Your rating: None