Classe de contexto no padrão de estratégia

10

Estou tentando entender o padrão de estratégia e me perguntando: a classe de contexto deve ter ou posso deixar de fora sem comprometer o objetivo do padrão?

Fiquei com a impressão de que precisava de algum tipo de opção para ler diferentes tipos de arquivos, mas não queria apenas invadir algo e depois lidar com a refatoração (embora, é claro, sempre aconteça que o código possa ser refatorado, mas a ideia era: tente para ser o mais inteligente possível no design de antemão ...):

insira a descrição da imagem aqui

Imagem retirada da wikimedia

O cliente pode delegar diretamente para a interface Strategy ou há algo que eu perdi de entender sobre a classe 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();
    }
}

Portanto, acima é mostrada a classe de contexto ausente. O código adere ao padrão de estratégia?

panny
fonte
11
Como outro ponto interessante / importante, gostaria de chamar a atenção de que o conceito de classes de tipos em linguagens funcionais é "simplesmente" o padrão de estratégia com os tipos en.wikipedia.org/wiki/Kind_(type_theory) ). Ambos são apenas um mecanismo de implementação do polimorfismo ad-hoc.
AndreasScheinert
Isso está (longe ou menos) relacionado ao Java 8 Project Lambda? O artigo da Wikipedia é muito denso para eu entender de uma só vez, mas se isso faz parte da base teórica para o uso eficiente dos recursos futuros do Java (ou programação em geral), investirei felizmente mais tempo nele.
panny
11
Muito longe, mas eu diria que sim, as classes de tipo precisam. Uma linguagem de programação que suporta tipos mais altos. Esse seria o caso de scala e Haskell. Meu argumento aqui foi que o polimorfismo (ad hoc) é implementado de maneira diferente e, se você recuar, poderá aprender algumas idéias sobre o polimorfismo em geral.
precisa saber é o seguinte

Respostas:

13

No seu exemplo, a chamada de código readFilefaz parte do construtor Client. Esse método é o "contexto" que você está procurando . O padrão de estratégia não precisa literalmente de uma "classe de contexto" e, na primeira versão do seu código, o objeto de estratégia (o "Reader" no seu caso) pode residir apenas em uma variável local. Especialmente quando existe apenas um "método estratégico" ("readFile") a ser chamado.

No entanto, se a sua base de código cresce de uma versão para a seguinte, é improvável que cada vez mais métodos "estratégicos" sejam chamados, e a decisão de qual estratégia aplicar e a execução dos "métodos estratégicos" ocorrerão em momentos diferentes e em lugares diferentes do seu código. Então você começa a refatorá-los para manter a lógica em um só lugar. Isso levará diretamente a uma implementação semelhante ao diagrama da sua pergunta.

Doc Brown
fonte
5

Certamente. Padrões são apenas diretrizes. Você ainda precisará adaptar e aplicá-los corretamente para o problema em questão. Pessoalmente, raramente permito que a estratégia seja definida em tempo de execução; mais frequentemente, é especificado na construção ou transformado em uma fábrica.

Embora também se possa argumentar que setStrategyé privado e minha injeção está apenas usando o padrão como mostrado.

Telastyn
fonte
Isso significa que a classe Context representada pode ser deixada de fora sem comprometer o padrão? Ou, dito de outra forma, tudo bem quando minha classe cliente é a classe de contexto representada?
Panny
6
@panny - hesito em responder à pergunta porque indica que você perdeu o ponto da resposta e, de fato, os padrões. O padrão de estratégia permite variar o comportamento, fornecendo diferentes implementações concretas por trás de uma interface. É um conceito , não uma fórmula .
Telastyn