Clase de contexto en el patrón de estrategia

10

Estoy tratando de entender el patrón de estrategia y me pregunto: ¿es imprescindible la clase de contexto o puedo dejarla sin comprometer el propósito del patrón?

Tenía la impresión de que necesitaba algún tipo de cambio para leer diferentes tipos de archivos, pero no quería simplemente hackear algo y luego tratar con la refactorización (aunque, por supuesto, siempre sucede que el código se puede refactorizar, pero la idea era: intentar ser lo más inteligente posible en el diseño de antemano ...):

ingrese la descripción de la imagen aquí

Imagen tomada de wikimedia

¿Puede el cliente delegar directamente en la interfaz de la Estrategia o hay algo que acabo de perder de entender sobre la clase de contexto?

interface Reader {
    // read information from file and fill data list field of Client
    readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}

class Client{
    // strategic choice
    Reader r;

    // data list field
    List<Data> data;

    // Client Constructor
    public Client(){
        if(<file ends in .xls>)
            r = new ExcelReader();
        else
            r = new PdfReader();
        r.readFile();
    }
}

Entonces, arriba se muestra la clase de contexto que falta. ¿Se adhiere el código al patrón de estrategia?

panny
fuente
1
Como otro punto interesante / importante, me gustaría llamar su atención sobre que el concepto de clases de tipos en lenguajes funcionales es "simplemente" el patrón de estrategia con tipos en.wikipedia.org/wiki/Kind_(type_theory) ). Ambos son solo un mecanismo de implementación para el polimorfismo ad-hoc.
AndreasScheinert
¿Está esto (lejos o menos) relacionado con Java 8 Project Lambda? El artículo de Wikipedia es demasiado denso para que yo lo entienda de inmediato, pero si estos son parte de los antecedentes teóricos para usar eficientemente las próximas características de Java (o la programación en general), felizmente invertiré más tiempo en él.
panny
1
Muy lejos, pero yo diría que sí, las clases de tipos necesitan. Un lenguaje de programación que admite tipos superiores. Ese sería el caso de Scala y Haskell. Mi punto aquí fue que el polimorfismo (ad hoc) se implementa de manera diferente y si retrocede puede aprender algunas ideas sobre el polimorfismo en general.
AndreasScheinert

Respuestas:

13

En su ejemplo, la llamada de código readFilees parte del constructor del Cliente. Ese método es el "contexto" que está buscando . El patrón de estrategia no necesita una "clase de contexto" literalmente, y en la primera versión de su código, el objeto de estrategia (el "Lector" en su caso) puede residir solo en una variable local. Especialmente cuando solo hay que llamar un "método estratégico" ("readFile").

Sin embargo, si su base de código crece de una versión a la siguiente, no es improbable que se recurra a más y más métodos "estratégicos", y la decisión de qué estrategia aplicar y la ejecución de los "métodos estratégicos" sucederán en diferentes momentos y en diferentes lugares en tu código. Entonces comienzas a refactorizarlos para mantener la lógica en un solo lugar. Esto conducirá directamente a una implementación similar al diagrama en su pregunta.

Doc Brown
fuente
5

Ciertamente. Los patrones son solo pautas. Aún tendrá que adaptarlos y aplicarlos correctamente para el problema en cuestión. Personalmente, rara vez permito que la estrategia se establezca en tiempo de ejecución; más a menudo se especifica en la construcción o se hace girar en una fábrica.

Aunque también se podría argumentar que setStrategyes privado y mi inyección solo usa el patrón como se muestra.

Telastyn
fuente
¿Esto significa que la clase de contexto representada puede omitirse sin comprometer el patrón? O dicho de otra manera, ¿está bien cuando mi clase de cliente es la clase de contexto representada?
panny
66
@panny: dudo en responder la pregunta porque indica que has perdido el punto de la respuesta y, de hecho, patrones por completo. El patrón de estrategia le permite variar el comportamiento al proporcionar diferentes implementaciones concretas detrás de una interfaz. Es un concepto , no una fórmula .
Telastyn