Muitos dos desenvolvedores de software mais diligentes que conheço estão adotando a inversão do controle e a injeção de dependência para manipular referências a objetos. Vindo de uma perspectiva de jogos em Flash, não conheço todos os meandros dos estúdios AAA; portanto, eles são usados no mundo dos jogos de varejo?
30
Respostas:
Você chama isso de 'desenvolvimento diligente de software', eu chamo de 'superengenharia dolorosa'. Isso não quer dizer que a inversão do controle seja ruim - na verdade, a definição básica dele é boa -, mas a proliferação de estruturas e métodos inteiros de trabalho para alcançar tudo isso é pouco insana, especialmente combinada com a maneira como as pessoas estão destruindo interfaces perfeitamente boas e limpas para injetar componentes intercambiáveis que você nunca trocará 99% do tempo. É o tipo de coisa que só poderia se originar do ambiente corporativo Java e fico feliz por não ter tanto apoio em outros lugares.
Frequentemente, o argumento é que, mesmo que você não troque componentes, você poderá testá-los isoladamente com objetos simulados e similares. No entanto, tenho medo de nunca comprar o argumento de que vale a pena inchar e complicar uma interface para poder testá-la melhor. O teste prova apenas uma coisa - que seus testes funcionam. Interfaces limpas e mínimas, por outro lado, ajudam muito a provar que seu código funciona.
Então, a resposta curta: sim, mas não da maneira que você está pensando. Às vezes, quando você precisa de um comportamento intercambiável, passa um objeto para um construtor que determina parte do comportamento do novo objeto. É sobre isso.
fonte
Padrão de Estratégia , Composição , Injeção de Dependência , todos estão intimamente relacionados.
Como o Padrão de Estratégia é uma forma de Injeção de Dependência, se você observar mecanismos como o Unity, por exemplo, eles serão completamente baseados nesse princípio. O uso de Componentes (Padrão de Estratégia) está profundamente incorporado a todo o mecanismo.
Um dos principais benefícios, além da reutilização de componentes, é evitar as temidas hierarquias profundas de classe.
Aqui está um artigo de Mick West que fala sobre como ele introduziu esse tipo de sistema na série de jogos Tony Hawk da Neversoft.
Evolua sua hierarquia
fonte
Parece haver muita confusão sobre o padrão de Inversão de Controle (IoC). Várias pessoas o equipararam ao Padrão de Estratégia ou a um Modelo de Componentes, mas essas comparações não captam realmente o que é a IoC. IoC é realmente sobre como uma dependência é obtida. Deixe-me lhe dar um exemplo:
No exposto acima, é claro que
Sprite.Load
depende de aFileReader
. Quando você deseja testar o método, precisa do seguinte:Os dois primeiros são óbvios, mas se você deseja garantir que o tratamento de erros funcione conforme o esperado, você também precisa do número 3. Nos dois casos, você potencialmente diminuiu bastante os testes, pois agora eles precisam ir para o disco e você provavelmente tornou seu ambiente de teste mais complicado.
O objetivo da IoC é dissociar o uso do comportamento de sua construção. Observe como isso difere do padrão de estratégia. Com o padrão Estratégia, o objetivo é encapsular um pedaço reutilizável de comportamento, para que você possa estendê-lo facilmente no futuro; não tem nada a dizer sobre como as estratégias são construídas.
Se reescrevéssemos o
Sprite.Load
método acima, provavelmente terminaríamos com:Agora, dissociamos a construção do leitor de seu uso. Portanto, é possível trocar um leitor de teste durante o teste. Isso significa que seu ambiente de teste não precisa mais de um sistema de arquivos, arquivos de teste e pode simular facilmente eventos de erro.
Observe que eu fiz duas coisas na minha reescrita. Eu criei uma interface
IReader
que encapsulava algum comportamento - ou seja, implementava o padrão de estratégia. Além disso, mudei a responsabilidade de criar o leitor certo para outra classe.Talvez não precisemos de um novo nome de padrão para descrever o acima. Parece-me uma mistura dos padrões de Estratégia e Fábrica (para contêineres IoC). Dito isto, não tenho certeza de que motivos as pessoas estão contestando esse padrão, pois fica claro que ele resolve um problema real e, certamente, não é óbvio para mim o que isso tem a ver com Java.
fonte
Eu diria que é uma ferramenta entre muitas, e é usada ocasionalmente. Como tenpn disse, qualquer método que introduza vtables (e geralmente qualquer indireção extra) pode ter uma penalidade de desempenho, mas isso é algo com o qual devemos nos preocupar apenas com código de baixo nível. Para código estrutural de alto nível que não é realmente um problema, e a IoC pode ter benefícios positivos. Tudo para reduzir dependências entre classes e tornar seu código mais flexível.
fonte
Tenho que concordar com Kylotan neste. "Injeção de dependência" é uma solução Java feia para uma falha conceitual feia de Java, e a única razão pela qual alguém está olhando para ela em outras linguagens é porque o Java está se tornando a primeira linguagem para muitas pessoas, quando realmente não deveria.
Inversão de controle, por outro lado, é uma idéia útil que existe há muito tempo e é muito útil quando feita corretamente. (Não da maneira Java / Injection de Dependency.) Na verdade, você provavelmente faz isso o tempo todo se estiver trabalhando em uma linguagem de programação sã. Quando eu li pela primeira vez toda essa coisa do "COI", todo mundo estava falando, fiquei completamente desapontado. Inversão de controle nada mais é do que passar um ponteiro de função (ou ponteiro de método) para uma rotina ou objeto para ajudar a personalizar seu comportamento.
Essa é uma ideia que existe desde os anos 50. Está na biblioteca padrão C (o qsort vem à mente) e está em todo lugar no Delphi e .NET (manipuladores / delegados de eventos). Ele permite que o código antigo chame o novo código sem precisar recompilar o código antigo e é usado o tempo todo nos mecanismos de jogo.
fonte
Não na minha experiência. O que é uma pena, pois o código dos jogos precisa ser muito adaptável, e essas abordagens definitivamente ajudariam.
No entanto, deve-se dizer que os dois métodos podem, em C ++, introduzir tabelas virtuais onde antes não existiam, trazendo consigo um desempenho adequado.
fonte
Eu não sou um desenvolvedor profissional de jogos, e só tentei implementar a IoC em C ++ uma vez, então isso é apenas especulação.
No entanto, eu suspeito que os desenvolvedores de jogos suspeitariam da IoC porque isso significa:
1 / projetando muitas interfaces e muitas classes pequenas
2 / tendo praticamente todas as chamadas de função sendo vinculadas ultimamente
Agora, pode ser uma coincidência, mas ambos tendem a ser um pouco mais complicados e / ou problemáticos para performances em C ++ (que é amplamente usado em jogos, não é?) Do que em Java, onde a IoC se generalizou (provavelmente porque era relativamente fácil de fazer, ajuda as pessoas a projetar hierarquias de objetos mais saudáveis e porque alguns acreditavam que poderia transformar a escrita de um aplicativo em Java em escrita em XML, mas esse é outro debate: P)
Estou interessado nos comentários, se isso não faz nenhum sentido;)
fonte