De que serve um monte de peças de carros sentadas em uma pista de corrida fazendo alguém?
Se tudo o que a sua classe de carro faz é reter peças, é tão útil quanto uma bolsa de peças molhadas.
Uso
Como motorista, o que eu quero é algo que eu possa controlar. Isso responde quando peço velocidade. Que lida com os trilhos. Isso pode parar rapidamente.
O que eu quero é uma classe de carro que seja utilizável. Que posso dizer para fazer as coisas sem ter que pensar em como o carburador funciona. Eu só penso no pedal do acelerador. Como eles estão conectados não é algo que me preocupa. Isso é abstração.
Injeção de dependência
A injeção de dependência não tem nada a ver com isso. Quando estou dirigindo, não estou pensando em como foi construído. Contanto que funcione, eu não me importo com a forma como eles montam.
Não, o DI é o que permite à minha equipe trocar rapidamente meus pneus por pneus melhores quando começa a chover na pista. É bom poder fazer isso sem ter que entrar em um carro completamente diferente.
O DI é realmente sobre seguir um princípio: Separar o uso da construção.
Um carro que pode instalar pneus novos a 150 km / h pode parecer legal, mas acho que não vai ganhar nenhuma corrida com um pneu instalando uma engenhoca.
O DI é sobre a instalação de suas peças de maneira que a equipe de pit chegue a elas. Quando você usa new
no mesmo local que programa o comportamento, é como se estivesse soldando o carburador no lugar. Certifique-se de que uma tocha de acetileno possa removê-la, mas considere o uso de porcas e parafusos primeiro.
Isso é o que DI é. Claro que não é tão fácil quanto new
criar algo assim que você perceber que deseja. Em vez disso, você deve escrever um código separado que saiba como montar seu carro. Mas com certeza torna mais fácil mudar as coisas mais tarde. E isso significa que você não precisa arrastar uma montadora de automóveis pela pista com você.
Construção
Algo, em algum lugar, precisa saber se os pneus são da Goodyear. Onde então colocar o código de construção do carro? Se não o carro, então a equipe do pit? Não. A pista? Não. Todos eles têm código de comportamento. Código que deve ser executado durante a corrida. A construção do carro deve acontecer antes da corrida em um local removido do código de comportamento. Mark Seemans chamou esse lugar de Raiz da Composição . A maioria das pessoas chama isso de principal.
É um padrão simples. Principalmente, construa o gráfico de objetos e chame um método comportamental em um objeto no gráfico de objetos. É isso aí. Este é o único lugar em que a construção e o comportamento devem estar juntos.
Isso não significa que a construção deva ser uma pilha de códigos processuais, todos dispostos sequencialmente em main. Você é livre para usar todas as ferramentas no idioma para fazer a construção. Só não misture isso com comportamento.
Fazer isso na linguagem e não usar alguma estrutura de DI ou contêiner de IoC é chamado de DI puro . Funciona muito bem. Tem há muito tempo. Costumávamos chamá-lo de passagem de referência .
Ferramentas DI
O que uma ferramenta DI compra para você são os detalhes da construção movidos para um idioma diferente (xml, json, qualquer que seja) que impõe a separação entre construção e comportamento. Se você não confia que seus colegas programadores não usem new
quando não deveriam, isso pode ser atraente.
A desvantagem é que é tentador deixar os detalhes da ferramenta de DI se espalharem por toda a base de código. Às vezes, infectar a base de código com anotações proprietárias. Os exemplos que eles fornecem certamente encorajam isso. A ferramenta tende a se mover para o espaço da linguagem até que você não possa apenas anunciar o trabalho como um trabalho de programação Java, mas como um trabalho de programação Java / Spring.
Princípios de design
Durante idades, eu estava programando aulas de carro porque era óbvio para mim que eu precisava de uma aula de carro se estiver programando uma lógica de carro. Mas com o DI não é tão óbvio para mim. Ainda me perguntando, é idiomático para o DI não criar uma classe Car se eu não tiver um papel definido para isso?
Acho que você está aprendendo sobre abstração e mudando como decide que uma aula é necessária. Isso é bom. Mas isso não é sobre DI. O DI não ajuda a decidir se você precisa de uma aula de carro. O DI ajuda a impedir que o carro saiba e, portanto, se importa, se os pneus são da Goodyear. O DI ajuda a impedir que a pista saiba se os carros são fabricados no Japão.
Uma das questões mais fundamentais no design de software é "o que sabe sobre o quê?" Essa é a principal coisa que um diagrama UML mostra. Quando você inventa algo que está alcançando, é uma interface com a coisa concreta à qual está vinculado. O carro agora precisa saber que os pneus são da Goodyear. O que é meio chato se a Michelin quiser patrociná-lo.
Evitar fazer isso é chamado seguindo o princípio da inversão de dependência . Formalmente, um módulo de alto nível (como a classe de carro) não deve depender diretamente de módulos de baixo nível (como a classe GoodyearTire). Deve depender de uma abstração (como uma interface do Tyre).
Uma maneira de evitar isso é chamada Inversão de controle . Aqui a ênfase está na alteração do fluxo de controle. Os pneus movem o carro ou o carro move os pneus? Pensar nisso da maneira certa nos permite não acoplar estaticamente o carro e os pneus. O DI é uma maneira específica de seguir a Inversão do controle.
Nada disso informa se você precisa de uma aula de carro. Se você estiver programando a "lógica do carro", é bom que exista um lugar para mantê-lo, em vez de espalhá-lo por todos os lugares. Apenas não se iluda pensando que a lógica de construção do carro é a mesma que a lógica de comportamento do carro, de modo que tudo tem que viver no mesmo lugar. Mas se você não tem um rolo definido para um carro, também não precisa. Corra com motocicletas pela pista, se quiser.
Quero dizer, não há problema em ter um SteeringWheel para dirigir, BoltsAndNuts nas rodas para a equipe de pit e todos os tipos de outras interfaces engraçadas sem ter uma instância que represente um carro como um todo?
DI ou não DI, é bom ter uma instância que represente um carro como um todo, mas essa instância não é algo que eu queira saber diretamente se não for necessário. Dê-me uma abstração do carro para que eu não precise me preocupar se ele funciona com gás, diesel ou eletricidade quando o uso. Isso é apenas algo que eu deveria me preocupar quando eu estiver construindo ou mantendo. É bom se o código que usa o carro não precisa saber ou se importar com o funcionamento. "Eu não sei. Eu não quero saber."