O padrão de estratégia e a injeção de dependência nos permitem definir / injetar objetos em tempo de execução. Qual é a diferença entre o padrão de estratégia e injeção de dependência?
95
O padrão de estratégia e a injeção de dependência nos permitem definir / injetar objetos em tempo de execução. Qual é a diferença entre o padrão de estratégia e injeção de dependência?
Respostas:
DI e Strategy funcionam da mesma maneira, mas Strategy é usado para dependências mais refinadas e de curta duração.
Quando um objeto é configurado com uma Estratégia "fixa", por exemplo, quando o objeto é construído, a distinção entre Estratégia e DI fica borrada. Mas em um cenário de DI é mais incomum que as dependências dos objetos mudem durante suas vidas, enquanto isso não é incomum com Strategy.
Além disso, você pode passar estratégias como argumentos para métodos, enquanto o conceito relacionado de injeção de argumento de método não é difundido e é usado principalmente no contexto de teste automatizado apenas.
A estratégia foca na intenção e incentiva você a criar uma interface com diferentes implementações que obedecem ao mesmo contrato comportamental. DI é mais sobre apenas ter uma implementação de algum comportamento e fornecê-lo.
Com o DI você pode decompor seu programa por outras razões além de apenas ser capaz de trocar partes da implementação. Uma interface usada em DI com apenas uma implementação é muito comum. Uma "Estratégia" com apenas uma implementação concreta (nunca) não é um problema real, mas provavelmente está mais perto de DI.
fonte
in a DI scenario it is more unusual that the dependencies of objects change during their lifetimes, while this is not uncommon with Strategy
A diferença é o que eles estão tentando alcançar. O padrão Strategy é usado em situações em que você sabe que deseja trocar as implementações. Como exemplo, você pode querer formatar dados de maneiras diferentes - você pode usar o padrão de estratégia para trocar um formatador XML ou CSV, etc.
A injeção de dependência é diferente porque o usuário não está tentando alterar o comportamento do tempo de execução. Seguindo o exemplo acima, podemos estar criando um programa de exportação XML que usa um formatador XML. Em vez de estruturar o código assim:
você 'injetaria' o formatador no construtor:
Existem algumas justificativas para a injeção de dependência, mas a principal é para teste. Você pode ter um caso em que tenha um mecanismo de persistência de algum tipo (como um banco de dados). No entanto, pode ser difícil usar um banco de dados real quando você está executando testes repetidamente. Portanto, para seus casos de teste, você injetaria um banco de dados fictício, para não incorrer nessa sobrecarga.
Usando este exemplo, você pode ver a diferença: sempre planejamos usar uma estratégia de armazenamento de dados, e é aquela que passamos (a instância de banco de dados real). No entanto, no desenvolvimento e nos testes, queremos usar dependências diferentes, por isso injetamos diferentes concreções.
fonte
Você pode usar o DI como um padrão de estratégia, então você pode trocar o algoritmo que é necessário para cada cliente, mas o DI pode ir além disso, pois é uma maneira de apenas desacoplar as partes de um aplicativo, que não fariam parte de o padrão de estratégia.
Seria arriscado dizer que o DI é apenas um padrão de estratégia renomeado, uma vez que começa a diluir o que o padrão de estratégia realmente serve, IMO.
fonte
Cara, injeção de dependência é um padrão mais geral, e é sobre dependência de abstrações, não concreções e faz parte de cada padrão, mas o padrão de estratégia é uma solução para um problema mais específico
esta é a definição da wikipedia:
DI:
Padrão de estratégia:
fonte
Estratégias são coisas de nível superior usadas para mudar a forma como as coisas são computadas. Com a injeção de dependência, você pode alterar não apenas como as coisas são calculadas, mas também o que está lá.
Para mim, fica claro ao usar testes de unidade. Para a execução do código de produção, você tem todos os dados ocultos (ou seja, privados ou protegidos); ao passo que, com os testes de unidade, a maioria dos dados são públicos, então posso ver com os Asserts.
Exemplo de estratégia:
Observe que não há dados públicos diferentes entre as estratégias. Nem há métodos diferentes. Ambas as estratégias compartilham as mesmas funções e assinaturas.
Agora, para a injeção de dependência:
Usar:
Observe as 2 últimas verificações. Eles usaram os dados públicos no teste duplo que foi injetado na classe em teste. Não pude fazer isso com o código de produção por causa do princípio de ocultação de dados. Eu não queria ter um código de teste de propósito especial inserido no código de produção. Os dados públicos deveriam estar em uma classe diferente.
O duplo de teste foi injetado. Isso é diferente de apenas uma estratégia, pois afetou os dados e não apenas as funções.
fonte
A injeção de dependência é um refinamento do padrão de estratégia que explicarei brevemente. Freqüentemente, é necessário escolher entre vários módulos alternativos em tempo de execução. Todos esses módulos implementam uma interface comum para que possam ser usados de forma intercambiável. O objetivo do padrão de estratégia é remover o fardo de decidir sobre qual dos módulos usar (ou seja, qual "estratégia concreta" ou dependência) encapsulando o processo de tomada de decisão em um objeto separado que chamarei de objeto de estratégia.
A injeção de dependência refina o padrão de estratégia não apenas decidindo qual estratégia concreta usar, mas também criando uma instância da estratégia concreta e "injetando-a" de volta no módulo de chamada. Isso é útil mesmo se houver apenas uma única dependência, pois o conhecimento de como gerenciar (inicializar, etc.) a instância de estratégia concreta também pode estar oculta dentro do objeto de estratégia.
fonte
Na verdade, a injeção de dependência também é muito semelhante ao padrão Bridge. Para mim (e de acordo com a definição), o padrão Bridge é para acomodar diferentes versões da implementação, enquanto o padrão Strategy é para uma lógica totalmente diferente. Mas o código de amostra parece estar usando DI. Então talvez DI seja apenas uma técnica ou implementação?
fonte
Estratégia é uma arena para usar suas habilidades de injeção de dependência. Maneiras reais de implementar injeção de dependência são as seguintes: -
Porém, há uma coisa que faz com que a estratégia se destaque. Como você sabe, no Unity, quando o aplicativo é inicializado, todas as dependências são definidas e não podemos alterá-las mais. Mas a estratégia oferece suporte à mudança de dependência do tempo de execução. Mas NÓS temos que administrar / injetar a dependência, não a responsabilidade da Estratégia!
Na verdade, a estratégia não fala sobre injeção de dependência. Se necessário, isso pode ser feito através do Abstract Factory dentro de um padrão Strategy. Estratégia fala apenas em criar uma família de classes com interface e 'brincar' com ela. Durante o jogo, se descobrirmos que as classes estão em um nível diferente, temos que injetá-lo nós mesmos, mas não o trabalho de Estratégia.
fonte
Se considerarmos os princípios SOLID - usamos o padrão de estratégia para o princípio aberto e fechado e injeção de dependência para o princípio de inversão de dependência
fonte