Estou refatorando um aplicativo PHP e estou tentando fazer o máximo possível de injeção de dependência (DI).
Sinto que tenho uma boa noção de como funciona e certamente posso ver minhas aulas se tornando muito mais enxutas e robustas.
Estou refatorando para injetar uma dependência em vez de criar um novo objeto dentro da classe, mas em algum momento terei que criar alguns objetos, ou seja, use a new
palavra-chave temida .
O problema que encontrei agora é em que ponto posso realmente criar novos objetos? Parece que vou terminar em uma classe de nível superior, criando um monte de novos objetos, pois não há mais para onde ir. Isso parece errado.
Li alguns blogs que usam classes de fábrica para criar todos os objetos e você injeta a fábrica em outras classes. Você pode chamar os métodos de fábrica, e a fábrica cria o novo objeto para você.
Minha preocupação em fazer isso agora é que minhas aulas de fábrica serão new
gratuitas para todos! Eu acho que isso pode ser bom, pois são classes de fábrica, mas existem algumas regras a serem seguidas ao usar um padrão de fábrica e DI, ou estou indo muito longe aqui?
fonte
new
. É claro que existem alguns pontos de entrada nos quais você precisa chamar o contêiner de IoC, mas não deve haver muitos. Normalmente, você configura o IoC uma vez e depois pede que uma classe seja resolvida por solicitação. No caso do MVC, normalmente é o controlador.Respostas:
Depois de pesquisar um pouco sobre isso, parece que (como mencionado em um comentário acima) a classe de nível superior de que eu estava falando se chama Raiz de Composição .
De fato, parece ser a solução aceita adicionar a criação de todos os objetos nessa raiz de composição (ou fazer referência a um contêiner de IoC daqui).
Minha preocupação original com isso era que essa classe de nível superior acabaria sendo um pouco confusa. Isso é verdade até certo ponto, mas os profissionais pesam os contras. Por exemplo, posso ver a legibilidade, testabilidade e capacidade de manutenção de todas as minhas outras classes.
A classe de nível superior pode ser um pouco confuso, cheio de
new
eset_property()
mas eu tenho que dizer que eu realmente prefiro ter todo este código em um só lugar, em vez de espalhados por todo as outras classesOutra página útil discutindo resultados de desempenho desse método aqui
fonte
Uma classe de fábrica terá
new
aspergida nela. Seria criar qualquer objeto que você está solicitando e provavelmente as dependências desse objeto. Como o trabalho das fábricas é instanciar o objeto correto para você ternew
nesta classe não é uma coisa ruim.O DI é para que você tenha um design fracamente acoplado. Você pode fazer alterações em seu aplicativo alterando a dependência fornecida a cada objeto. Tornando seu aplicativo flexível, extensível e fácil de testar.
No nível superior, você terá um código que instanciará algumas fábricas, configurará conexões com os serviços e enviará uma resposta. Ele terá uma quantidade razoável de
new
chamadas estáticas para instanciar objetos necessários para o seu aplicativo. É aí que isso pertence.fonte
Meus dois centavos aqui:
Você não informa se está usando uma estrutura de injeção de dependência. Eu acho que você definitivamente deveria. Use algo que ofereça os recursos necessários: /programming/9348376/guice-like-dependency-injection-frameworks-in-php .
Você normalmente usa a configuração ou um ponto central para a instanciação dos objetos iniciais que compõem seu aplicativo. O contêiner criará os objetos para você.
Você acessa objetos (serviços, provedores, controladores ...) por meio do contêiner de IoC. Ele criará um objeto de forma transparente, se necessário, ou fornecerá uma referência à instância existente apropriada.
Obviamente, dentro de sua implementação específica de objetos, você pode instanciar outros objetos nos quais não precisa de DI (estruturas de dados, tipos personalizados, etc.), mas isso é programação normal.
Normalmente, você usa um Factory se deseja que a estrutura de IoC instancie alguns objetos de IoC através de suas fábricas (isso é necessário ao instanciar um objeto em particular, requer algum trabalho extra). Se você pode simplesmente criar seus objetos com "new Object ()" e definir algumas propriedades, não necessariamente deseja usar um padrão de Fábrica.
Em outras palavras, eu diria que o uso de um padrão Factory para uma classe ou grupo de classes depende de como você deseja modelar essas classes, não de usar DI (a menos que sua implementação de DI exija explicitamente fábricas, o que é incomum).
Você também configura sua estrutura de IoC para usar um Factory quando estiver usando uma biblioteca de terceiros que já exija o uso de um Factory. Nesse caso, você não tem controle sobre isso e precisa informar ao seu contêiner de IoC: "ei, quando solicito uma dessas interfaces, você deve usar esta fábrica para fornecer uma instância apropriada".
Nesse caso, parece que você não precisa usar padrões de fábrica para esses objetos / serviços / controladores / o que quer que seja, e você pode simplesmente configurar sua IoC para instanciar com "nova" a classe apropriada e injetar todo o resto.
Espero que ajude.
fonte
doing DI manually beats the whole purpose of using an Inversion of Control container
- Se com isso você quer dizer "... que está centralizando suas dependências em um arquivo de configuração", então você está certo, porque isso é tudo que um contêiner de IoC realmente faz. O objetivo real do DI é desacoplar, e você pode fazer isso fornecendo suas dependências em um método construtor. Você não precisa de uma estrutura de DI para fazer isso.