Skip to content

3. Inversão de controlo IoC

Vamos agora debruçar-nos sobre o conceito de inversão de controlo (IoC, Inversion of Control) utilizado pelo Spring para configurar as aplicações. Para ilustrar este conceito, voltemos à arquitetura da nossa aplicação de teste anterior:

Para aceder aos dados do SGBD, a classe de teste deve utilizar os serviços de um objeto que implemente a interface [IArticlesDao], por exemplo, um objeto do tipo [ArticlesDaoPlainODBC]. Analisámos duas soluções possíveis para instanciar um objeto deste tipo:

  • na primeira solução, a própria classe de teste solicitava a instanciação de um objeto do tipo [ArticlesDaoPlainODBC]:
    <TestFixture()> _
    Public Class NunitTestArticlesDaoPlainOdbc

         ' o objeto a testar
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
             ' cria-se uma instância do objeto a testar
            articlesDao = New ArticlesDaoPlainODBC("odbc-firebird-articles", "SYSDBA", "masterkey")
        End Sub
...
    End Class

Existe uma dependência rígida no código relativamente ao nome da classe. Se a classe de implementação da interface [IArticlesDao] vier a mudar, o código do método [init] terá de ser alterado. Existem as seguintes relações entre os objetos:

A própria classe [NunitTestArticlesDaoPlainOdbc] toma a iniciativa de criar o objeto [ArticlesDaoPlainODBC] de que necessita. Voltando ao termo «inversão de controlo», dir-se-á que é ela que tem o «controlo» para criar o objeto de que necessita.

  • A segunda solução funciona de forma diferente. A classe de teste passou a ser a seguinte:
    <TestFixture()> _
    Public Class NunitSpringTestArticlesDaoPlainOdbc

         ' o objeto a testar
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
       ' recupera-se uma instância do criador de objetos Spring
            Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
       ' solicita-se a instanciação do objeto «articles dao»
            articlesDao = CType(factory.GetObject("articlesdao"), IArticlesDao)
        End Sub
    ...
    End Class

Este mecanismo poderia ser esquematizado da seguinte forma:

Aqui, a classe de teste não toma a iniciativa de solicitar a criação de um objeto [ArticlesDaoPlainODBC]. Limita-se a solicitar ao Spring uma referência a esse objeto. Se o objeto existir, o Spring devolve uma referência ao mesmo. Se não existir, cria-o. A classe de teste perdeu o controlo sobre a criação do objeto [ArticlesDaoPlainODBC]. Limita-se a solicitar uma referência a esse objeto. Esta solicitação irá, neste caso, obrigar o Spring a criar o objeto. Mas poderíamos imaginar, noutro contexto, que o objeto solicitado já tivesse sido criado a pedido da aplicação. Nesse caso, o Spring não recria o objeto, mas devolve uma referência ao objeto já existente (singleton). O conceito de Inversão de Controlo (IoC) significa, neste contexto:

  • que a aplicação nunca toma a iniciativa de criar os singletons de que necessita. Limita-se a solicitar referências aos mesmos.
  • É o Spring que toma a decisão de criar um singleton aquando do primeiro pedido de referência ao mesmo