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?


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.


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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.