Академический Документы
Профессиональный Документы
Культура Документы
Sum
ario
1 Introdu
c
ao
2 Princpio de Holywood
3 Padr
ao Inje
c
ao de Depend
encias
4 Inje
c
ao de Depend
encias aplicado a Reposit
orios e DAOs
5 Conclus
oes
6 Notas Bibliogr
aficas
Padr
oes de Software
Introdu
c
ao
ao
de Depend
encias pode ser utilizado para configurar um tipo particular de
dependencia, aquela existente entre repositorios e objetos de acesso a dados.
Essa discuss
ao e feita no contexto do framework Spring. Finalmente a Secao 5
apresenta as conclus
oes relativas ao conte
udo apresentado neste Captulo.
Princpio de Holywood
Em arquitetura de sistemas de software, ha um conceito importante denominado Princpio de Holywood, que esta associado `a frase N
ao nos chame,
nos o chamamos (traduc
ao da expressao original Do not call us, we will call
you). A origem dessa frase est
a associada `a atividade dos agentes de atores em
Holywood. Ao serem procurados por atores desconhecidos `a procura de uma
oportunidade para atuar, esses agentes fornecem a resposta padrao para que
esses atores n
ao entrem em contato e que, em vez disso, eles (os agentes) e que
irao entrar em contato no caso de surgir alguma oportunidade.
No contexto de arquitetura de software, o Princpio de Holywood quando
da construc
ao de um elemento de codigo (uma classe ou um componente) que
deve ser integrado ao c
odigo de um framework. Nesse contexto, tipicamente o
desenvolvedor implemente uma ou mais interfaces (fornecidas pelo proprio framework). A tempo de execuc
ao da aplicacao, o framework pode entao invocar
(chamar, call ) o c
odigo definido pelo programador. Repare que o framework invoca c
odigo implementado pelo programador por meio de acoplamento abstrato
e de polimorfismo. Em outras palavras, o framework faz as vezes do agente de
atores, que chama (telefona) os atores no momento em que achar adequado.
Padr
oes de Software
Padr
ao Inje
c
ao de Depend
encias
O padr
ao Injec
ao de Depend
encias (do original Dependency
Injection) e uma aplicac
ao particular do princpio de Holywood. O
contexto de uso desse padr
ao e aquele no qual um objeto que depende de
diversos outros deve ser construdo (i.e., instanciado). Dizemos que um objeto
X depende de outro Y quando, para fornecer corretamente seus servicos, X
precisar delegar parte desse servico para Y. Chamamos X de cliente, e Y de
fornecedor do servico. Em geral, um objeto pode depender de varios outros
objetos fornecedores.
Para enteder a aplicac
ao do padrao Injec
ao de Depend
encias, vamos
primeiramente considerar uma situacao em que esse padrao nao e usado. Para
isso, considere a Listagem 1. Diz-se que um elemento A (que pode ser uma
classe ou um componente) possui uma dependencia para outro B se A usa os
servicos fornecidos por B. Uma maneira de definir a dependencia e fazer com
que A instancie B. No trecho de codigo esquematico apresentado, a classe A
(cliente) cria explicitamente uma instancia de B (fornecedor).
Listagem 1: 1o cen
ario: classe A (cliente) cria explicitamente uma instancia de
B (fornecedor).
1
class A {
Padr
oes de Software
B b;
A() {
this.b = new B();
}
2
3
4
5
6
fazerAlgo() {
this.b.fazerAlgo();
}
7
8
9
10
ao de Depend
encias, em vez de o objeto cliente (i.e., dependente) instanciar cada objeto fornecedor de que precisa,
ele simplesmente recebe as referencias para seus fornecedores. A instanciacao
desses objetos fornecedores e realizada por outro componente. Os objetos fornecedores s
ao passados, por exemplo, como parametros do construtor do objeto
dependente, ou como par
ametros de metodos modificadores (setXXX). Veja a
Listagem 2. Nesse trecho de c
odigo, podemos perceber que a instanciacao de
B fica a cargo de outro elemento que nao e A. Vamos chamar esse elemento
de injetor de depend
encias, posto que seu papel e instanciar B e passar a
referencia durante a construc
ao (instanciacao) de A. Repare que na Listagem
2, o elemento B pode ser uma classe concreta, uma classe abstrata ou mesmo
uma interface.
Listagem 2: 2o cen
ario: a instanciacao de B fica a cargo de outro elemento que
nao e A.
1
2
class A {
B b;
A(B b) {
this.b = b;
}
4
5
6
7
8
9
10
11
No 2o cen
ario, houve uma invers
ao do controle de instancia
c
ao das
depend
encias. Em particular, a instanciacao de B passa a ser feita externamente a A. O elemento A e agora mais flexvel ja que nao depende de uma im possvel passar como parametro uma instancia
plementac
ao especfica de B. E
de alguma classe que estende (ou implemente) B.
Pela discuss
ao acima, podemos concluir que Injec
ao de Depend
encias
e padr
ao de projeto que declara o seguinte:
Uma entidade n
ao deve obter entidades externas das quais ela
depende para realizar sua tarefa. Em vez disso, deve esperar
que outra entidade forne
ca essas depend
encias.
Padr
oes de Software
Inje
c
ao de Depend
encias aplicado a Reposit
orios
e DAOs
Uma aplicac
ao do padr
ao Injecao de Dependencia e no contexto da amarracao
entre reposit
orio e objetos de acesso a dados. Nessa Secao, apresentamos um
exemplo dessa amarrac
ao. Considere as classes DisciplinaRepo e DisciplinaDaoJpa do SCA.
Sem o uso do padr
ao injecao de dependencia, teramos possivelmente o
trecho de c
odigo similar ao da Listagem 3 para realizar a amarracao entre
objetos daquelas duas classes. Isso e ilustrado na Listagem 3.
Listagem 3: Amarrac
ao manual entre o cliente (DisciplinaRepo) e o fornecedor (DisciplinaDAOJpa).
1
2
3
A injec
ao por metodo modificador pressupoe que o cliente forneca um
metodo p
ublico que possa ser invocado pelo conteiner de IoC para que
este injete a referencia no momento adequado. Na listagem 7, repare a
existencia do metodo setDisciplinaDao. Com uma definicao adequada
realizada no arquivo de configuracao do Spring, toda vez que um objeto
DisciplinaRepositorio e criado na aplicacao, o conteiner automaticamente instancia um objeto cuja classe implemente a interface DisciplinaDao
e invoca o metodo setDisciplinaDao para passar essa referencia ao objeto
DisciplinaRepositorio recem-criado.
Listagem 4: Injec
ao por metodo (setter injection).
1
2
3
4
Padr
oes de Software
5
6
7
this.dao = dao;
}
...
A injec
ao por construtor pressupoe que o cliente forneca um construtor que
receba como par
ametro um objeto que corresponda `a referencia a ser injetada.
Um exemplo desse tipo de injecao e apresentado na listagem 5, na qual podemos reparar a existencia de um construtor. Mais um vez, com uma definicao
adequada realizada no arquivo de configuracao do Spring, toda vez que um objeto DisciplinaRepositorio e criado na aplicacao, o conteiner automaticamente instancia um objeto cuja classe implemente a interface DisciplinaDao
e passa esse objeto por meio do construtor.
Listagem 5: Injec
ao por construtor (constructor injection).
1
2
3
4
5
6
7
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- REPOSIT
ORIOS -->
<bean id="disciplinaRepositorio" class="br.cefetrj.sca.dominio.
DisciplinaRepositorio">
<property name="dao">
<ref local="disciplinaDao" />
</property>
</bean>
<bean id="turmaRepositorio" class="br.cefetrj.sca.dominio.
TurmaRepositorio">
Padr
oes de Software
<property name="dao">
<ref local="turmaDao" />
</property>
</bean>
<bean id="professorRepositorio" class="br.cefetrj.sca.dominio.
ProfessorRepositorio">
<property name="dao">
<ref local="professorDao" />
</property>
</bean>
18
19
20
21
22
23
24
25
26
27
28
</beans>
Uma forma alternativa e mais adequada de configurar a injecao de dependencias no Spring e por meio do uso de anotacoes. A anotacao relevante a
usar nesse caso e denominada Autowired. Veja a Listagem 7, que apresenta
um exemplo de uso dessa anotac
ao. Nesse exemplo, um repositorio deve ser injetado na classe de servico FornecerGradeService. Para isso, o atributo correspondente a esse reposit
orio e anotado com Autowired. Nessa alternativa, o
conteiner de IoC instanciar o repositorio e iniciar o atributo professorRepo.
Listagem 7: Exemplo de uso da anotacao @Autowired
1
@Autowired
private ProfessorRepo professorRepo;
3
4
5
6
7
8
9
Na alternativa de injec
ao com uso da anotacao Autowired, as definicoes
no arquivo de configurac
ao s
ao mais simples. A Listagem 8 apresenta um trecho
de um arquivo de configurac
ao que usa essa alternativa. Compare com o trecho
do arquivo apresentado na Listagem 6.
Listagem 8: Trecho do arquivo de contexto do framework Spring para configurac
ao de DI com anotac
oes.
1
2
3
4
5
6
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:
context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context
-3.0.xsd">
7
8
<context:annotation-config />
9
10
Padr
oes de Software
11
12
13
14
</beans>
Conclus
oes
o de Depend
Com o uso do padr
ao Injec
a
encias, uma referencia a um
objeto fornecedor pode ser passada para um objeto cliente. As duas
motivac
oes principais para usar esse mecanismo sao:
Aumentar a reusabilidade dos componentes.
Aumentar a testabilidade dos componentes
Uma vantagem do uso do padrao Injec
ao de Depend
encias e que ele
permite desacoplar componentes de uma solucao. Entrentato, esse padrao nao
e para ser usada em todas as situacoes de desenvolvimento. Isso porque seu
uso aumenta a complexidade da implementacao resultante, devido a indirecoes
adicionais. Avalie cuidadosamente a efetiva necessidade de adicionar flexibilidade ao projeto de software. Se essa flexibilidade for realmente necessaria, isso
conta a favor do uso da aplicac
ao do padrao Injec
ao de Depend
encia.
Notas Bibliogr
aficas
Ha diversos arcaboucos para IoC. Tres deles sao o Spring IoC (www.
springsource.org/), o Pico Container (http://picocontainer.
org/) e o Castle (http://www.castleproject.org/).
Martin Fowler ajudou a popularizar o conceito de Injecao de Dependencias
por meio do artigo intitulado Inversion of Control Containers and
the Dependency Injection pattern. Esse artigo pode ser encontrado na Internet no endereco http://martinfowler.com/articles/
injection.html.