Ao projetar um sistema, sou frequentemente confrontado com o problema de ter vários módulos (registro, acesso ao banco de dados, etc.) sendo usados pelos outros módulos. A questão é: como faço para fornecer esses componentes a outros componentes. Duas respostas parecem possíveis injeção de dependência ou usando o padrão de fábrica. No entanto, ambos parecem errados:
- As fábricas tornam o teste uma tarefa difícil e não permitem a troca fácil de implementações. Eles também não tornam as dependências aparentes (por exemplo, você está examinando um método, alheio ao fato de que ele chama um método que chama um método que chama um método que usa um banco de dados).
- A injeção de dependência aumenta massivamente as listas de argumentos do construtor e mancha alguns aspectos em todo o seu código. Situação típica é onde construtores de mais da metade das classes se parecem com isso
(....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d)
Aqui está uma situação típica com a qual tenho um problema: Tenho classes de exceção, que usam descrições de erro carregadas do banco de dados, usando uma consulta com parâmetro de configuração do idioma do usuário, que está no objeto de sessão do usuário. Portanto, para criar uma nova exceção, preciso de uma descrição, que exija uma sessão de banco de dados e a sessão do usuário. Portanto, estou fadado a arrastar todos esses objetos em todos os meus métodos para o caso de eu precisar lançar uma exceção.
Como faço para resolver esse problema?