quinta-feira, 7 de agosto de 2008

Análise e Crítica: "Inversion of Control Containers and the Dependency Injection Pattern"

O fraco acoplamento é um dos elementos mais cruciais no desenvolvimento de software orientado a objetos, pois este permite que a mudança em um objeto não exija mudanças em outros objetos. Este problema ocorre quando a mudança de implementação em um objeto "A" força mudanças em um objeto "B", onde normalmente o objeto "A" é o responsável pela criação do objeto "B" (forte acoplamento). Assim, a manutenção do software, reúso, escalabilidade e testes passam a ser tarefas difíceis de serem concretizadas. Além disso, localizar serviços independente da implementação é importante para cumprir com o princípio supracitado.

Neste contexto, Fowler[1] apresenta como os padrões "Dependency Injection" (ou Inversão de Controle) e "Service Locator" podem desacoplar objetos fortemente relacionados e corrigir independências entre objetos. No primeiro caso, é feita a utilização dos princípios de orientação a objetos tais como interface, herança e polimorfismo. A utilização de construtores, interfaces (menos utilizada) ou métodos set(s) permitem "injetar" - através do "assembler" - um objeto "B" à um objeto "A" que precise usufruir de serviços disponibilizados pelo objeto "B". Desta forma, o objeto "A" não precisa mais ter conhecimento dos atributos necessários para a criação do objeto "B", permitindo baixo acoplamento. No segundo caso, a idéia básica é ter um objeto (localizador) responsável por registrar serviços e associá-lo à uma chave. Um objeto "A" deve apenas recuperar uma instância do objeto "B" através deste localizador de serviços, passando a chave (normalmente em string) que esta instância está associada.

Fowler também discute quando utilizar as abordagens apresentadas. Ambas as abordagens propõem o baixo acoplamento, porém, a grande diferença entre elas está em como a implementação do objeto é disponibilizada ao objeto que deseja utilizá-lo. Por um lado, ao utilizar "Service Locator", uma requisição explícita ao responsável pela localização do serviço deve ser realizada, mantendo uma dependência com este objeto localizador. Por outro lado, na inversão de controle, não é realizada nenhuma requisição, visto que um objeto "A" recebe uma referência de um objeto "B" diretamente de construtores ou métodos set. Normalmente é mais difícil de entender e leva a problemas relacionados a debug. Desta forma, a escolha por qual das abordagens reflete na observação de onde a dependência se encontra.

Finalmente, os padrões permitem um melhor design, facilitando o reúso, o fraco acoplamento, e testes de componentes de software. Entretanto, acho que (1) a utilização de métodos get e set expõem os atributos de um objeto, violando o encapsulamento. Além disso, (2) acho que a utilização de construtores para injetar objetos pode tornar a inicialização de um objeto bastante confusa devido ao número de parâmetros que devem ser referenciados, apesar de "aliviar" o número de métodos set na classe. Entretanto, acho as abordagens plausíveis no que tange o fraco acoplamento entre objetos e a localização de serviços independentemente da implementação do mesmo.

Thiago Sales

[1] Martin Fowler. Inversion of control containers and the dependecy injection pattern. www.martinfowler.com, Janeiro 2004.

Um comentário:

Fabiano Amorim disse...

Ae Thiago, gostei do seu Blog.

Não entendi muito bem a parte que você fala sobre osw dois meios de diminuir o acoplamento. Não ficou muito claro para mim, estes dois meios.

Fabiano Amorim