Os padrões de projeto contribuem para a melhoria da qualidade do produto de software e, dessa forma, aplicá-los – e utilizar os melhores frameworks para isso – é assunto de grande importância para o mercado de desenvolvimento.
Um padrão de projeto de software, de forma geral, consiste numa solução reutilizável para um problema lógico recorrente. A aplicação de padrões pode se materializar em blocos de código, estratégias ou modelos de soluções.
Dentre os diversos catálogos de padrões existentes, atualmente destaca-se o catálogo GoF (Gang of Four), famoso principalmente após a publicação do clássico livro “Design Patterns: Elements of Reusable Object-Oriented Software” (Padrões de Projeto: soluções reutilizáveis de software Orientado a Objetos), em 1994, e o catálogo GRASP (General Responsibility Assignment Software Patterns), ambos voltados para o desenvolvimento orientado a objetos.
Neste contexto, o Model-View-Controller – MVC, ou Modelo-Visão-Controle – é um padrão de projeto que, diferente dos padrões dos catálogos GoF e GRASP, se aproxima da proposição de uma arquitetura de software. Inicialmente, ele foi criado para aprimorar a implementação de interfaces com o usuário, separando as representações internas de informação da camada com que o usuário da aplicação tem contato, deixando-a mais “magra”.
A divisão em três camadas com responsabilidades específicas é a essência do MVC. A camada de Modelo é responsável por representar o domínio da aplicação, ilustrando a informação que o caracteriza. Em outras palavras, o modelo representa os dados da aplicação e as regras de negócio que a gerenciam, devidamente encapsuladas. A camada de Visão (Visualização ou Apresentação) é responsável pelo contato direto com o usuário, em geral por meio de interfaces visuais e conteúdo renderizado. É essa camada que envia os comandos do usuário para o respectivo controlador, sendo capaz de, para isso, acessar dados do modelo. A camada de Controle, por sua vez, determina o comportamento da aplicação, interpretando as ações do usuário e traduzindo suas ações.
Para alguns autores, as principais vantagens da utilização do padrão MVC são:
• Camadas de visão magras e independentes permitem a criação de diversas visões, até mesmo em plataformas diferentes;
• A divisão de responsabilidades entre as camadas permite a reutilização de código e escalabilidade;
• É possível desenvolver as camadas em paralelo, otimizando o projeto do software.
Embora criada originalmente para aplicações desktop, essa divisão de responsabilidades se mostrou bastante conveniente em arquiteturas Web, tendo sido implementada nas mais diversas linguagens e com o suporte de vários frameworks. Neste momento vale destacar o Apache Struts, pioneiro na implementação do MVC para a linguagem Java.
O framework Spring, no entanto, é muito mais do que isso. Conforme a definição da própria iniciativa Spring, além do suporte para a arquitetura N camadas com o Spring MVC, fornece também uma implementação para os padrões Inversão de Controle e Injeção de Dependência (vide BOX 1), entre muitos outros recursos.
Inversão de Controle é um padrão de projeto em que a chamada de métodos é invertida, ou seja, não é determinada pelo programador, mas delegada a um componente que possa tomar conta dessa execução, chamado de container.
Embora haja alguma polêmica em torno dessa definição, a Injeção de Dependência é uma forma de aplicar a Inversão de Controle. Na Injeção de Dependência, o container é responsável por injetar em cada componente suas dependências que tiverem sido declaradas.
Nesse artigo vamos explorar o potencial do Spring MVC no desenvolvimento de uma aplicação Web e, além disso, faremos com que a que aplicação interaja com o banco de dados relacional MySQL. Para auxiliar na construção da camada de acesso a dados, simplificando a implementação das operações básicas da camada de persistência (inserção/alteração, exclusão e leitura), será utilizado o framework Hibernate.
De maneira similar ao Spring, o Hibernate é composto de diversas ferramentas (ORM, Search, Validator, etc.). No nosso exemplo será demonstrado o uso da ferramenta de mapeamento objeto-relacional (vide BOX 2) – principal objetivo do Hibernate – chamada Hibernate ORM.
Mapeamento Objeto-Relacional é a técnica utilizada para tornar possível a representação das classes da aplicação – projetadas a partir do paradigma da Orientação a Objetos – em entidades de um banco de dados relacional – projetadas a partir do paradigma Relacional e da Normalização.
O Hibernate ORM tem como objetivo tornar a associação entre os objetos da aplicação e a base de dados que irá persisti-los mais transparente. Isso simplifica a consulta ao banco de dados, livrando o desenvolvedor da tarefa manual de escrever a relação entre objetos da aplicação e as tabelas, dispensando, por exemplo, o uso de SQL.
Sendo assim, os objetos do front-end da aplicação serão construídos a partir de princípios da Orientação a Objetos, enquanto o back-end da aplicação seguirá conceitos e princípios de Normalização. Esses dois conceitos não são equivalentes e, quando sua relação é desenvolvida equivocadamente, ocorre um problema comumente intitulado de “incompatibilidade de impedância” (vide Box 3). O mapeamento objeto-relacional – e o Hibernate, por consequência – deve fornecer solução para esse tipo de problema.
São enquadradas como problemas de Incompatibilidade de Impedância (Object-relational Impedance Mismatch), as dificuldades encontradas quando objetos ou classes da aplicação têm seus atributos mapeados de maneira divergente dos elementos representados nas entidades de um banco de dados relacional. As divergências podem ser estruturais ou transacionais, ocorrendo por conta de diferenças em tipos de dados ou na forma pelas quais os dados são manipulados.
Nesse artigo, construiremos uma pequena aplicação web que interage com um banco de dados MySQL. O exemplo será desenvolvido com o apoio da IDE Eclipse e, por ser uma aplicação web, é necessária a instalação de um container Web Java – aqui será utilizado o Tomcat 6. Embora dê mais ênfase ao padrão MVC e sua implementação no Spring, bem como à implementação da camada de persistência no Hibernate, nosso estudo descreve também, de forma breve, a implementação de uma arquitetura de ...