1
FUNDAÇÃO EDUCACIONAL JAYME DE ALTAVILA – FEJAL
CENTRO DE ESTUDOS SUPERIORES DE MACEIÓ – CESMAC
FACULDADE DE CIÊNCIAS EXA...
2
ADAILTON PIMENTEL REIS
PROGRAMAÇÃO ORIENTADA A ASPECTOS COM
PERSISTÊNCIA NO DESENVOLVIMENTO DE SISTEMAS
Arapiraca, dezem...
3
ADAILTON PIMENTEL REIS
PROGRAMAÇÃO ORIENTADA A ASPECTOS COM
PERSISTÊNCIA NO DESENVOLVIMENTO DE SISTEMAS
COMISSÃO EXAMINA...
4
Dedico este trabalho:
à minha mãe, Maria Aparecida;
à minha namorada, Thaysa;
ao meu primo, Minervo
5
AGRADECIMENTOS
Primeiramente a Deus, pois sem sua ajuda, nada teria sido possível.
Ao meu orientador Professor José Carl...
6
Crê, trabalha e não temas,
Deus te apóia e te guarda.
Tentações a vencer?
Deus te dá a resistência.
Mais trabalho na vid...
7
RESUMO
Este trabalho relata o ganho de produtividade ao se utilizar os recursos da persistência
juntamente com o paradig...
8
ABSTRACT
This paper describes the gains in productivity one we decide to use the features of
persistence along with aspe...
9
LISTA DE FIGURAS
Figura 1: Mapeamento objeto-relacional ...................................................................
10
LISTA DE TABELAS
Tabela 1: Tipos de anotações ............................................................................
11
SUMÁRIO
INTRODUÇÃO .......................................................................................................
12
3.1.2 Interfaces Criteria e Query .................................................................. 32
3.1.2.1 Consult...
13
INTRODUÇÃO
No desenvolvimento de sistemas orientados a objetos são identificados, durante a etapa de
análise, os requis...
14
Portanto, o uso do paradigma da orientação a aspectos, juntamente com o conceito de
mapeamento objeto-relacional atravé...
15
1 PERSISTÊNCIA DE DADOS
Um dos pincipais problemas do desenvolvimento de sistemas nos últimos anos, quando o
paradigma ...
16
As duas formas mais utilizadas no mercado de desenvolvimento de softwares e muito
questionadas sobre qual a melhor form...
17
e apoiando o desenvolvimento de sistemas. Os subtópicos abaixo ilustram como é feita a
codificação de mapeamento via JD...
18
public class Conexao {
private static Connection conexao;
public static void abreConexao(){
try{
Class.forName("org.pos...
19
Com a utilização destas ferramentas, uma nova camanda é criada, a camada de
persistência, que é uma biblioteca que perm...
20
@Entity
@Table(name="pessoa")
public class Pessoa implements java.io.Serializable {
@Id
@GeneratedValue(strategy=Genera...
21
! @Id – define a chave primária;
! @Table – informa o nome da tabela mapeada.
Os tipos de anotações acima, foram descri...
22
! Em seguida é instanciado um objeto do tipo AnnotationConfiguration,
onde através do método configure é passado o arqu...
23
Segundo (BAUER;KING, 2005, pg. 37 – 39) a persistência realizada
automaticamente por ferramentas, em especial, através ...
24
2 PROGRAMAÇÃO ORIENTADA A ASPECTOS
O paradigma da orientação a aspectos é uma nova metodologia de programação que veio
...
25
2.1 ENTRELAÇAMENTO E ESPALHAMENTO DE CÓDIGO
O entrelaçamento de código ocorre quando torna-se necessário inserir chamad...
26
2.1.2 ILUSTRANDO O ESPALHAMENTO DE CÓDIGO
Os códigos sublinhados e em negrito representam as linhas destinadas à audito...
27
Figura 3 – Combinação aspectual
Fonte: JUNIOR, Vicente Goetten; WINCK, Diogo Vinícius
Esta separação entre unidade de n...
28
Figura 6 – Componentes da programação orientada a aspectos
Fonte: JUNIOR, Elidio Mendes
Linguagem de componentes permit...
29
primeira parte. É um mecanismo bastante similar a um método, cuja
função é declarar o código que deve ser executado ant...
30
2.2 CÓDIGO ESCRITO EM LINGUAGEM DE COMPONENTES
public class Comunicador{
public static void entrega(String mensagem)
{
...
31
contenham qualquer tipo de retorno, enquanto que o ( .. ) representa métodos que contenham
qualquer tipo de parâmetro.
32
3 ESTUDO DE CASO APLICANDO OS CONCEITOS DE AOP E
PERSISTÊNCIA
Este capítulo relata um estudo caso onde foi aplicada os ...
33
3.1.1 INTERFACE CONFIGURATION
Um objeto deste tipo realiza as configurações iniciais do hibernate, como por
exemplo, o ...
34
Assim como na consulta realizada, esta também obtém o usuário através do
primeiro nome, só que utilizando a interface Q...
35
3.1.5 INTERFACE TRANSACATION
Esta inferface abstrai de forma transparente a aplicação dos detalhes dos diversos
tipos d...
36
public Cliente(){
}
public int getId(){
return id;
}
public String getNome(){
return nome;
}
public void setNome(String...
37
sobrepõem explicitamente este método herdam a implementação definida
por java.lang.Object, o qual compara a identidade ...
38
Figura 7 – Estado de um objeto e suas transições
Fonte: BAUER, Christian; KING, Gavin
3.1.9 ANOTAÇÕES ( ANNOTATIONS )
A...
39
@Entity Indica que a classe é um entity bean (classe entidade) a ser persistida
@Id Declara o identificador da entidade...
40
na verdade, são apenas pontos de entrada mentalizados, como marcadores imaginários de pontos
onde se deseja executar po...
41
Chega um momento durante o desenvolvimento de um sistema que é preciso modificar
um sistema, seja adicionando um novo a...
42
3.3 ESTUDO DE CASO
Voltando ao estudo de caso, a equipe constatou durante o desenvolvimento com a
ferramenta hibernate,...
43
if (locais.size() >0) {
throw new InsercaoIlegalException();
}
}
local.setDescricao(novoLocal.getDescricao());
session....
44
As linhas que estão em negrito referem-se as linhas que estão se repetindo. Portanto, esses
métodos que possuem estas l...
45
ControleSessao. Em seguida é declarado um outro ponto de atuação, denominado auxiliar
que agrupa os pontos de junção qu...
46
}
public static ArrayList<Local> listaLocaisDescricao(String descricao) {
ArrayList<Local> locais = (ArrayList<Local>) ...
47
CONCLUSÃO
É fato que, cumprir os prazos descritos no projeto do software, torna-se um fator essencial
para que as empre...
48
desenvolvedora e a indústria de software, e principalmente, nas faculdades e universidades
começarem a desenvolver proj...
49
REFERÊNCIAS BIBLIOGRÁFICAS
BAUER, Christian; KING, Gavin. Hibernate em Ação. 2. ed. Rio de Janeiro: Ciência Moderna,
20...
50
SILVA, João Carlos da; et al. Estratégias de Persistência em Software Orientado a Objetos:
definição e implementação de...
51
52
Próximos SlideShares
Carregando em…5
×

Tcc aop-e-persistencia

273 visualizações

Publicada em

Programação Orientada a Aspectos com Persistência no Desenvolvimento de Sistemas

Publicada em: Tecnologia
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
273
No SlideShare
0
A partir de incorporações
0
Número de incorporações
3
Ações
Compartilhamentos
0
Downloads
4
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Tcc aop-e-persistencia

  1. 1. 1 FUNDAÇÃO EDUCACIONAL JAYME DE ALTAVILA – FEJAL CENTRO DE ESTUDOS SUPERIORES DE MACEIÓ – CESMAC FACULDADE DE CIÊNCIAS EXATAS E TECNOLÓGICAS – FACET ADAILTON PIMENTEL REIS PROGRAMAÇÃO ORIENTADA A ASPECTOS COM PERSISTÊNCIA NO DESENVOLVIMENTO DE SISTEMAS Arapiraca, dezembro de 2007
  2. 2. 2 ADAILTON PIMENTEL REIS PROGRAMAÇÃO ORIENTADA A ASPECTOS COM PERSISTÊNCIA NO DESENVOLVIMENTO DE SISTEMAS Arapiraca, dezembro de 2007 Trabalho Final de Graduação apresentado à Faculdade de Ciências Exatas e Tecnológicas – FACET, como requisito a obtenção de Título de Bacharel em Análise de Sistemas, sob a orientação do Professor José Carlos Milito.
  3. 3. 3 ADAILTON PIMENTEL REIS PROGRAMAÇÃO ORIENTADA A ASPECTOS COM PERSISTÊNCIA NO DESENVOLVIMENTO DE SISTEMAS COMISSÃO EXAMINADORA Aprovado em ____/____/____ _________________________________________________ Prof. José Carlos Milito Centro de Estudos Superiores de Maceió Orientador __________________________________________ Professor A Centro de Estudos Superiores de Maceió Avaliador __________________________________________________ Professor B Centro de Estudos Superiores de Maceió Avaliador ___________________________________________________ Professor C Centro de Estudos Superiores de Maceió Avaliador Metodológico Trabalho Final de Graduação apresentado à Faculdade de Ciências Exatas e Tecnológicas – FACET, como requisito a obtenção de Título de Bacharel em Análise de Sistemas, sob a orientação do Professor José Carlos Milito.
  4. 4. 4 Dedico este trabalho: à minha mãe, Maria Aparecida; à minha namorada, Thaysa; ao meu primo, Minervo
  5. 5. 5 AGRADECIMENTOS Primeiramente a Deus, pois sem sua ajuda, nada teria sido possível. Ao meu orientador Professor José Carlos Milito, pelo grande apoio e dedicação durante a elaboração deste trabalho, como também, críticas e dicas ao referente trabalho. A minha namorada pela paciência,compreensão e apoio. Aos meus familiares pelo incentivo e compreensão pelos momentos de ausência. E mais uma vez, a minha mãe por ter se esforçado sempre, para que eu tivesse uma boa educação e chegasse até aqui, sempre honrando seu suor.
  6. 6. 6 Crê, trabalha e não temas, Deus te apóia e te guarda. Tentações a vencer? Deus te dá a resistência. Mais trabalho na vida? Deus te iluminará. Se desejas servir Deus te concede os meios. Por mais lutas à frente Segue e confia em Deus. Emmanuel
  7. 7. 7 RESUMO Este trabalho relata o ganho de produtividade ao se utilizar os recursos da persistência juntamente com o paradigma da orientação a aspectos no desenvolvimento de sistemas orientado a objetos, principalmente em sistemas mais complexos, dotados de vários interesses sistêmicos, como por exemplo, a própria peristência automatizada, que gera códigos espalhados e entrelaçados durante a implementação. Neste trabalho também são apresentados alguns trechos de códigos simples, bem como, um estudo de caso demonstrando na prática os benefícios decorrentes da utilização destas duas metodologias. Palavras-chave: Entrelaçamento de código, Espalhamento de código, Interesses cruzados, Mapeamento objeto-relacional, Orientação a Aspectos, Persistência, Separação de interesses. .
  8. 8. 8 ABSTRACT This paper describes the gains in productivity one we decide to use the features of persistence along with aspect oriented programming at developing of object oriented applications, specially in complex programs, composed by several systemic concerns, such as automated persistence, which generates spread and crosscut code during its implementation. At this paper are presented some fragments of simple code, as well as a case study showing in a practical approach the benefits of those two technologies. Keywords: code crosscutting, code spreading, crosscut concerns, object-relational mapping, aspect orientation, persistence, separation of concerns
  9. 9. 9 LISTA DE FIGURAS Figura 1: Mapeamento objeto-relacional ...................................................................................... 15 Figura 2: Interesses cruzados ........................................................................................................ 24 Figura 3: Combinação aspectual ................................................................................................... 26 Figura 4: Decomposição de interesses .......................................................................................... 27 Figura 5: Interesses de login no tomcat ........................................................................................ 27 Figura 6: Componentes da programação orientada a aspectos ..................................................... 27 Figura 7: Estado de um objeto e suas transições .......................................................................... 36
  10. 10. 10 LISTA DE TABELAS Tabela 1: Tipos de anotações ....................................................................................................... 37 Tabela 2 : Componentes elementares do AspectJ ........................................................................ 38 Tabela 3: Tipos de pontos de junção ............................................................................................ 38 Tabela 4: Tipos de adendos (advices) .......................................................................................... 39
  11. 11. 11 SUMÁRIO INTRODUÇÃO ................................................................................................................. 13 1 PERSISTÊNCIA DE DADOS .............................................................................. 15 1.1 Mapeamento objeto-relacional via JDBC ....................................................... 16 1.1.1 Exemplo de codificação de uma classe entidade ........................... 17 1.1.2 Exemplo de codificação de um mapeamento manual via JDBC.17 1.2 Mapeamento objeto-relacional via persistência ............................................ 18 1.2.1 Exemplo de código de uma classe entidade utilizando o recurso de anotações ............................................................................................................................. 19 1.2.2 Exemplo de como é realizada a persistência automatizada ........ 21 1.3 Mapeamento via JDBC x Mapeamento via Persistência ............................ 22 1.3.1 Vantagens da JDBC .............................................................................. 22 1.3.2 Desvantagens da JDBC ........................................................................ 22 1.3.3 Vantagens da persistência automatizada ......................................... 22 1.3.4 Desvantagens da persistência automatizada ................................... 23 2 PROGRAMAÇÃO ORIENTADA A ASPECTOS ................................. 24 2.1 Entrelaçamento e Espalhamento de Código .................................................. 24 2.1.1 Ilustrando o Entrelaçamento de Código .......................................... 25 2.1.2 Ilustrando o Espalhamento de Código ............................................. 25 2.2 Código Escrito em Linguagem de Componentes ......................................... 29 2.3 Código Escrito em Linguagem de Aspectos ................................................. 30 3 ESTUDO DE CASO APLICANDO OS CONCEITOS DE AOP E PERSISTÊNCIA .............................................................................................................. 31 3.1 Recursos do Hibernate ......................................................................................... 31 3.1.1 Interface Configuration ........................................................................ 31
  12. 12. 12 3.1.2 Interfaces Criteria e Query .................................................................. 32 3.1.2.1 Consulta Utilizando a Interface Criteria ........................... 32 3.1.2.2 Consulta Utilizando a Interface Query ............................. 32 3.1.3 Interface Session .................................................................................... 33 ` 3.1.4 Interface SessionFactory ...................................................................... 33 3.1.5 Interface Transaction ............................................................................ 33 3.1.6 O que são Classes Persistentes ........................................................... 34 3.1.7 Identidade de Objetos e de Banco de Dados .................................. 35 3.1.8 Objetos persistentes, transientes e destacados ................................ 36 3.1.9 Anotações ................................................................................................ 37 3.2 AspectJ .................................................................................................................... 37 3.3 Estudo de Caso ...................................................................................................... 40 3.3.1 Código sem a Aplicação da AOP ...................................................... 41 3.3.2 Código de Implementação do Aspecto ............................................ 42 3.3.3 Código após a Aplicação do Aspecto .............................................. 43 CONCLUSÃO .................................................................................................................... 45 REFERÊNCIAS BIBLIOGRÁFICAS ................................................................ 46
  13. 13. 13 INTRODUÇÃO No desenvolvimento de sistemas orientados a objetos são identificados, durante a etapa de análise, os requisitos funcionais e não funcionais. Geralmente os requisitos não funcionais, são os pontos denominados interesses cruzados, ou seja, que não fazem diretamente parte das unidades de negócio do sistema. Estes interesses dificultam o desenvolvimento, teste e até mesmo a sua manutenção. Para tornar mais claro onde ocorrem estas dificuldades que os requisitos não funcionais ocasionam, abaixo estão relacionados alguns tipos de interesses cruzados: a) Gerenciamento de sessões; b) Logging; c) Manutenção da segurança; d) Persistência; e) Profiling; f) Transações. A metodologia de desenvolvimento de sistemas dominante no mercado, que é a orientação a objetos, foi criada com o objetivo de abstrair entidades do mundo real na forma de objetos. Esse paradigma tornou o desenvolvimento mais produtivo, bem como a manutenção e o reuso. Porém, algumas propriedades não podem ser separadas em uma única unidade de função, porque participam de várias unidades no sistema, ocasionando espalhamento e entrelaçamento de código. Um outro problema de desenvolvimento de sistemas orientados a objetos, ocorre quando uma aplicação que utiliza este paradigma, precisa se comunicar com um banco de dados relacional. Ou seja, representar objetos em linhas nas tabelas do banco de dados. Para esta dificuldade, foram desenvolvidos vários frameworks que tem por base a persistência automatizada e transparente de objetos. Para realizar esse tipo de persistência, uma nova camanda é criada, a camada de persistência.
  14. 14. 14 Portanto, o uso do paradigma da orientação a aspectos, juntamente com o conceito de mapeamento objeto-relacional através da persistência transparente e automatizada, torna o desenvolvimento de sistemas orientados a objetos mais produtivo, a manutenção facilitada e um maior reuso de código. Todos esses fatores são essenciais diante de um mercado globalizado e concorrido, onde a demanda por software é maior que o tempo com que este é desenvolvido. Outro fator muito importante e que justifica o benefício que a utilização destas duas abordagens irá trazer, é a alta escalabilidade, ou seja, a capacidade do software crescer sem prejudicar sua funcionalidade e qualidade. Com isso, a equipe de desenvolvimento e até mesmo o desenvolvedor terá uma alta possibilidade de cumprir prazos de entrega, para suprir essa demanda, cada vez maior por software.
  15. 15. 15 1 PERSISTÊNCIA DE DADOS Um dos pincipais problemas do desenvolvimento de sistemas nos últimos anos, quando o paradigma da orientação a objetos tornou-se popular, tem sido a compatibilização entre este paradigma e o dos bancos de dados relacionais. Alguns dos problemas dessa incompatibilidade (herança versus joins, encapsultamento versus projeção, etc.) já é bem conhecida nas indústrias de software e na comunidade de desenvolvedores, pois ocasionam muitas dificuldades durante todo o processo de desenvolvimento de algum aplicativo orientado a objetos que utiliza os recursos dos bancos relacionais. Entretando, para contornar estes problemas, existem algumas soluções, como por exemplo, os bancos de dados orientados a objetos, que praticamente eliminam os problemas citados. Porém, alguns fatores levam a indústria e a comunidade de desenvoldores a utilizarem os banco de dados relacionais, dentre eles pode-se citar: a alta maturidade, os principais problemas relacionados ao armazenamento e recuperação de dados foram praticamente solucionados e o imenso investimento das empresas nesse tipo de tecnologia. Devido a esses e outros fatores, que torna-se imprescindível um meio de armazenar instâncias de objetos, como também recuperar os objetos armazenados, mantendo o estado dos objetos conservado, mesmo após a aplicação ter sido finalizada, nas tabelas de um banco de dados relacional. Para esta finalidade, é necessário fazer um mapeamento objeto-relacional. Neste mapeamento, as classes e os atributos do sistema são mapeados para tabelas e campos/colunas, e a persistência pode ser feita de forma transparente (o programador não precisa saber como está sendo realizada a persistência), utilizando-se de uma ferramenta para esta finalidade, ou através da codificação manual. Assim, objetos em memória são armazenados e recuperados no banco, e objetos do banco são trazidos para a memória sempre que necessário. Abaixo, segue uma figura que demonstra o mapeamento. Figura 1 – Mapeamento Objeto-Relacional Fonte: SILVA, João Carlos da.
  16. 16. 16 As duas formas mais utilizadas no mercado de desenvolvimento de softwares e muito questionadas sobre qual a melhor forma para realizar a persistência de dados são: o mapeamento objeto-relacional via JDBC e o mapeamento objeto-relacional através de uma ferramenta que realiza a persistência automaticamente (por exemplo, o hibernate e o ibatis). 1.1 MAPEAMENTO OBJETO-RELACIONAL VIA JDBC O significado para mapeamento objeto-relacional é o mesmo tanto via JDBC manualmente, como também, para a persistência feita automaticamente, pois quando é implementado um código SQL que executa um select e extrais os resultados para seus objetos, ou até mesmo, quando é persistido um objeto para dentro do banco de dados, seja qual for a forma utilizada, o mapeamento está sendo realizado. A JDBC é, em muitos aspectos, uma API de baixo nível, que muitas vezes exige dos desenvolvedores o conhecimento das particularidades do banco de dados. Ela trabalha no mesmo nível do banco de dados, sendo o acesso as informações armazenadas feito através de comandos SQL. Por trabalhar no mesmo nível que o banco de dados, esta forma de mapeamento é a mais eficiente, desde que o programador tenha o domínio da linguagem SQL. Logicamente, apenas ter o domínio de SQL não é tudo, pois é necessário saber como é realizada a comunicação entre o aplicativo e o banco de dados. Portanto, para realizar essa conexão é necesssário ter, além da máquina virtual, um driver JDBC. Este driver é geralmente fornecido junto com o banco de dados ou através de um download, sem custo adiconal. Mas, o que são esses drivers JDBC? São bibliotecas Java, ou seja, arquivos JAR que podem ser copiados para qualquer sistema operacional, que não necessitam de uma configuração prévia e nem que seja instalado um cliente nativo do banco de dados para funcionar. Além do mais, não é preciso editar arquivo de configuração e nem mesmo de executar algum painel de controle administrativo. Resumidamente, através da JDBC, uma aplicação java pode se conectar a qualquer banco de dados relacional, submeter comandos SQL para execução e recuperação dos resultados gerados pela execução desses comandos. Além do mais, a JDBC permite acesso aos metadados do banco de dados, permitindo a construção de ferramentas para administração do próprio banco
  17. 17. 17 e apoiando o desenvolvimento de sistemas. Os subtópicos abaixo ilustram como é feita a codificação de mapeamento via JDBC. 1.1.1 EXEMPLO DE CODIFICAÇÃO DE UMA CLASSE ENTIDADE public class Pessoa { private int cod_cliente; private String nome; private String endereco; private String rg; public Pessoa(String nome,String endereco,String rg) { this.setNome(nome); this.setEndereco(endereco); this.setRg(rg); } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getRg() { return rg; } public void setRg(String rg) { this.rg = rg; } public int getCod_cliente() { return cod_cliente; } } Esta uma classe entidade Pessoa que será mapeada para uma tabela de um banco de dados, através de codificação manual via JDBC. O mapeamento será feito como se segue no próximo subtópico abaixo. 1.1.2 EXEMPLO DE CODIFICAÇÃO DE UM MAPEAMENTO MANUAL VIA JDBC import java.sql.*;
  18. 18. 18 public class Conexao { private static Connection conexao; public static void abreConexao(){ try{ Class.forName("org.postgresql.Driver"); conexao = DriverManager.getConnection ("jdbc:postgresql:projeto","postgres","postgres"); }catch(Exception e){ e.printStackTrace(); } } public static void cadastraPessoa(String nome,String rg){ try{ Statement s=conexao.createStatement(); s.executeUpdate("insert into cliente(nome,rg)" + " values ('"+nome+"','" + '"+rg+"')"); }catch (Exception e){ e.printStackTrace(); } } Esta implementação foi realizada seguindo os seguintes passos, primeiramente é feita uma chamada a Class.forName() que garante o carregamento do driver JDBC do banco de dados na memória da JVM. Em seguida é realizada uma chamada a DriverManager.getConnection() que cria uma conexão ( interface Connection) com o banco de dados através da String passada como primeiro argumento e o segundo e o terceiro argumentos se referem ao login e senha para acesso ao banco. O objeto Connection retornado pelo DriverManager é utilizado para criar um comando SQL (objeto do tipo Statement) pela chamada a createStatement(). E finalmente, é executado o comando SQL através da chamada ao método executeUpdate(). 1.2 MAPEAMENTO OBJETO-RELACIONAL VIA PERSISTÊNCIA Para utilizar os recursos dos bancos de dados relacionais, através de alguma linguagem orientada a objetos (por exemplo, JAVA) e ainda assim aproveitar os conceitos do paradigma de orientação a objetos, é feito um mapeamento objeto-relacional utilizando ferramentas que realizam a persistência através de mecanismos que façam (semi) automaticamente a conversão entre objetos e tabelas.
  19. 19. 19 Com a utilização destas ferramentas, uma nova camanda é criada, a camada de persistência, que é uma biblioteca que permite a realização do processo de persistência (armazenamento e manutenção do estado dos objetos em algum meio não volátil, de forma transparente). A camada de persistência, diferentemente da JDBC, oferece uma melhor abstração orientada a objetos, pois através dela, os seguintes mapeamentos podem ser realizados (herança, agregação etc). Isto faz com que os desenvolvedores se sintam como estivessem realmente programando orientado a objetos. E essa é a idéia principal deste tipo de ferramenta, além do objetivo de livrar o programador de 95% de código SQL gerado manualmente. Existem diversas ferramentas que realizam a persistência automática, sendo as mais conhecidas o hibernate e o ibatis. A realização do mapeamento objeto-relacional utilizando estas ferramentas procede-se através de três passos básicos: identificação das classes persistentes através de técinas de mapeamento, edição dos arquivos de configuração XML (atualmente algumas ferramentas estão com suporte ao recurso de anotações) para fazer o mapeamento objeto-relacional e por fim, a implementação destes arquivos em classes java. Além do mais, persistir dados utilizando-se de ferramentas que realizam de forma transparente, torna a codificação menos tediosa, menos propensa a erros e principalmente, o desenvolvedor fica com mais tempo para se dedicar as otimizações SQL. Diferentemente, o código SQL implementado manualmente torna o desenvolvimento menos produtivo, cansativo e com uma maior probabilidade de ocorrer erros e como consequência, o desenvolvedor perde tempo na verificação desses erros, ao invés de manter o foco nas otimizações SQL. Portanto, para ilustrar como é feita a persistência automatizada por ferramentas, serão mostrados nos subtópicos abaixo, assim como foi, nos subtópicos sobre mapeamento manual, exemplos de código de uma classe entidade e da classe que irá persistir objetos ou seja, as instâncias da classe entidade ( Pessoa ). 1.2.1 EXEMPLO DE CÓDIGO DE UMA CLASSE ENTIDADE UTILIZANDO O RECURSO DE ANOTAÇÕES package testandohibernate; import javax.persistence.*;
  20. 20. 20 @Entity @Table(name="pessoa") public class Pessoa implements java.io.Serializable { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE) @Column(name="codigo_cliente") private int codigo_cliente; @Column(nullable=false,length=40,insertable=true,updatable=true) private String nome; @Column(unique=true,nullable=false,insertable=true,updatable=true) private long rg; public Pessoa() { } public int getCodigo_cliente() { return codigo_cliente; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public long getRg() { return rg; } public void setRg(long rg) { this.rg = rg; } } É importante ressaltar que, diferentemente da classe persistente ( Pessoa ) que foi codificada manualmente, a ferramenta hibernate exige que o construtor de uma classe persistente seja sem argumentos, como pode ser visto no subtópico acima. Tendo isto em mente, a respectiva classe persistente foi mapeada através dos seguintes recursos de anotações da ferramenta hibernate: ! @Entity – informa que a classe mapeada é persistente; ! @Column – informa o nome da coluna mapeada para o atributo; ! @GeneratedValue – define o mecanismo de definição da chave primária;
  21. 21. 21 ! @Id – define a chave primária; ! @Table – informa o nome da tabela mapeada. Os tipos de anotações acima, foram descritos de forma bem resumida, pois no capítulo 3 serão abordados todas as características, componentes e mecanismos da ferramenta hibernate. 1.2.2 EXEMPLO DE COMO É REALIZADA A PERSISTÊNCIA AUTOMATIZADA package testandohibernate; import org.hibernate.*; import org.hibernate.cfg.*; public class Cadastra { public static void main(String args[]) { Configuration cfg = new AnnotationConfiguration(); cfg.configure("hibernate.cfg.xml"); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); Pessoa pessoa = new Pessoa(); pessoa.setNome("Adailton Pimentel"); pessoa.setRg(1751936); session.save(pessoa); tx.commit(); session.close(); } } O mapeamento da classe persistente ( Pessoa ) utilizando a metodologia da persistência automatizada da ferramenta hibernate é realizado da seguinte forma: ! Primeiramente é preciso configurar o hibernate editando um arquivo xml (hibernate.cfg.xml) com as propriedades referentes ao banco de dados que será ligado ao aplicativo, mas, antes de tudo, é de suma importância importar os pacotes org.hibernate e org.hibernate.cfg para pode utilizar as classes e seus respectivos métodos;
  22. 22. 22 ! Em seguida é instanciado um objeto do tipo AnnotationConfiguration, onde através do método configure é passado o arquivo de mapeamento das propriedades de inicialização do banco de dados; ! Depois é criado uma SessionFactory ( fábrica de sessões ) que deve ser chamada apenas uma vez, visto que os objetos deste tipo armazenam os mapeamentos que são pesados e muito lentos de criar. ! E finalmente é aberta uma sessão através da interface Session, para em seguida ser iniciada uma transação para que possa ser feita a persistência do objeto ( pessoa ) pelo método save. 1.3 MAPEAMENTO VIA JDBC X MAPEAMENTO VIA PERSISTÊNCIA Para demonstrar a comparação entre JDBC e persistência automatizada por ferramentas de uma maneira mais clara e concisa, serão abordadas as vantagens e desvantagens destes dois tipos de ORM. 1.3.1 VANTAGENS DA JDBC a) Curva de aprendizado menor, visto que os desenvolvedores estão familiarizados e conhecem bem SQL; b) Maneira eficiente de acessar dados; c) Não é necessário editar arquivos de configuração; d) Não necessita de nenhuma configuração prévia; e) Opção que normalmente oferece melhor performance. 1.3.2 DESVANTAGENS DO JDBC a) Códigos intrusivos ( invasivos ) b) Código realizado manualmente; c) Mais linhas de código ( LOC ) d) Oferece uma abstração orientada a objetos bastante limitada; 1.3.3 VANTAGES DA PERSISTÊNCA AUTOMATIZADA
  23. 23. 23 Segundo (BAUER;KING, 2005, pg. 37 – 39) a persistência realizada automaticamente por ferramentas, em especial, através da ferramente hibernate, apresenta as seguintes vantagens: a) Desempenho: A persistência automatizada permite muito mais otimizações a serem usadas o tempo todo, enquanto que a persistência codificada manualmente permite normalmente fazer algumas otimizações, algumas com relação ao tempo. b) Manutenção: A persistência automatizada reduz substancialmente as Locs (Linhas de código). Apesar de que, a contagem de de linhas de código ser um modo discutível de medir a complexidade de um aplicativo. c) Produtividade: Os desenvolvedores se concentram no problema de negócios. Pois, todas as tarefas relacionadas a SQL estão encapsuladas, ou seja, são feitas transparentemente. 1.3.4 DESVANTAGENS DA PERSISTÊNCIA AUTOMATIZADA a) Eficiência menor que o possível com acesso direto ao banco, pois a persistência automatizada exige uma camada adicional; b) Falta de padronização; c) Maior complexidade: pois o desenvolvedor necessita conhecer um sofisticado mecanismo cheio de opções e estratégias. Fazendo uma análise do que foi exposto nas abordagens de vantagens e desvantagens acima, apesar da persitência automatizada possuir certas desvantagens, pode-se chegar a conclusão de que ela é a solução que melhor se adapta em ambientes que exigem uma maior produtividade, alta escalabilidade e manutenção facilitada e também para que a indústria, como também, o desenvolvedor autônomo, possa cumprir os prazos de entrega do software, sem perder a qualidade e a eficiência do mesmo. Além do mais, apesar do problema da complexidade, o ganho de produtividade é indiscutível, e compensa amplamente a curva de aprendizado.
  24. 24. 24 2 PROGRAMAÇÃO ORIENTADA A ASPECTOS O paradigma da orientação a aspectos é uma nova metodologia de programação que veio complementar o atual paradigma da orientação a objetos, com a finalidade de procurar resolver os problemas encontrandos no desenvolvimento de sistemas orientados a objetos, como o entrelaçamento de código e o espalhamento de código que ocasionam muitas dificuldades aos desenvolvedores. Segundo (JUNIOR;WINCK, 2006, pg. 42) a programação orientada a aspectos foi criada no fim da década de 1990, mais precisamente no ano de 1997, em Palo Alto, nos laboratórios da Xerox, por Gregor Kiczales, John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Videira Lopes, Jean-Marc Loingtier e John Irwin. Kiczales e sua equipe tiveram essa iniciativa porque tinham como meta, criar uma forma de se implementar as características ortogonais fora do escopo da linguagem de componentes, para que cada desenvolvedor pudesse manter o foco no módulo de sua responsabilidade, para no final ser realizado a integração. Interesses estes como os que podem ser observados na figura 2. Figura 2 – Interesses cruzados Fonte: RESENDE, Antônio Maria Pereira de; SILVA, Claudiney Calixto da A separação de intereses visa tornar o sistema mais modularizado, proporcionando três pontos chaves e essenciais no desenvolvimento de sistemas, pontos esses que são a reusabilidade, manutenabilidade e escalabilidade. E esses pontos chaves fazem parte dos objetivos da programação orientada a aspectos.
  25. 25. 25 2.1 ENTRELAÇAMENTO E ESPALHAMENTO DE CÓDIGO O entrelaçamento de código ocorre quando torna-se necessário inserir chamadas de responsabilidades de uma classe em outra, ocasionando código intrusivo ou invasivo. O espalhamento de código ocorre quando existe várias chamadas de métodos de uma instância de uma classe em diversas outras classes, tornando a manutenabilidade e a produtvidade trabalhosa. Além do mais, a reusabilidade também é dificultada. Para ilustar tais problemas, segue-se abaixo exemplos de códigos relacionados ao entrelaçamento e ao espalhamento de código. 2.1.1 ILUSTRANDO O ENTRELAÇAMENTO DE CÓDIGO As linhas de código em negrito e sublinhadas representam chamadas de responsabilidades da classe Ponto na classe Reta. public class Ponto { int x; int y; public Ponto(int x, int y) { this.x = x; this.y = y; } public int getX() { return this.x; } public int getY() { return this.y; } } public class Reta{ int x1,x2; int x2,y2; public Reta(Ponto x, Ponto y) { this.x1 = x.getX(); this.y1 = y.getY(); this.x2 = x.getX(); this.y2 = y.getY(); } }
  26. 26. 26 2.1.2 ILUSTRANDO O ESPALHAMENTO DE CÓDIGO Os códigos sublinhados e em negrito representam as linhas destinadas à auditoria. public class Conta{ private String num; protected double saldo; public double getSaldo() { Log.registrar(“Conta”,num, “getSaldo”); return saldo; } public void sacar(double valor) { if(saldo >= valor && valor > 0) Log.registrar(“Conta”,num, “sacar”); saldo = saldo – valor; } public void depositar(double valor) { if(valor > 0) Log.registrar(“Conta”,num, “depositar”); Saldo = saldo + valor; } } Portanto, seu principal objetivo consiste em separar o código referente ao negócio do sistema dos códigos referentes aos interesses transversais, de uma forma bem definida e centralizada, possibilitando assim um nível maior de abstração no desenvolvimento de software. Além do mais, estando bem separados e em locais bem definidos, os componentes podem ser melhor reutilizados e a sua manutenção e legibilidade torna-se mais agradável. Isto irá acarretar uma nova forma de desenvolvimento de sistemas, pois, durante a análise até sua implementação, deverá ser mantido o foco na identificação dos pontos de junção, que são pontos geralmente referentes aos requisitos não funcionais, que ocasionam os já citados problemas do entrelaçamento e espalhamento de código, para depois, através de um combinador aspectual ( weaver ), que como o próprio nome diz, fazer a combinação dos códigos escritos em linguagem de componentes com os códigos escritos em linguagem de aspectos. A figura abaixo, ilustra esse processo de combinação.
  27. 27. 27 Figura 3 – Combinação aspectual Fonte: JUNIOR, Vicente Goetten; WINCK, Diogo Vinícius Esta separação entre unidade de negócio e interesses transversais, denomina-se, separação ou decomposição de interesses, ilustrada através da figura abaixo, que mostra um prisma de identificação dos interesses filtrados dos requerimentos. Figura 4 – Decomposição de Interesses Fonte: JUNIOR, Elidio Mendes Como exemplo de interesses sistêmicos pode-se citar a sincronização de objetos concorrentes, distribuição, tratamento de exceções, coordenação de múltiplos objetos, persistência, auditoria, dentre outros exemplos. A seguite figura abaixo ilustra o interesse sitstêmico de Loggin do tomcat, onde as linhas tracejadas nas barras verticais ( classes ), representam códigos invasivos. Figura 5 – Interesses de Login no TomCat Fonte: JUNIOR, Vicente Goetten; WINCK, Diogo Vinícius Um sistema orientado a aspectos é composto pela linguagem de componentes, linguagem de aspectos, combinador de aspectos, programas escritos em linguagem de componentes e os programas escritos em linguagem de aspectos, conforme é demonstrado na figura 6.
  28. 28. 28 Figura 6 – Componentes da programação orientada a aspectos Fonte: JUNIOR, Elidio Mendes Linguagem de componentes permite aos desenvolvedores escrever programas que implementam as funcionalidades básicas do sistema, ou seja, os módulos relacionados as regras de negócio. A linguagem de aspectos, como o próprio nome diz, permite aos desenvolvedores implementar os interesses sistêmicos ou interesses cruzados (crosscuting concerns). O combinador de aspectos, faz a junção de códigos implementados na linguagem de componentes, com códigos implementados na linguagem de aspectos. Programas escritos em linguagem de componentes são as funcionalidade básicas do sistema, enquanto que programas escritos em linguagem de aspectos representam os interesses sistêmicos. Portanto, para desenvolver sistemas orientados a aspectos, é necessário uma ferramenta, e a mais utilizada é o aspectJ, por ser uma plataforma madura, por existir muitos documentos tanto na internet, como também, em livros e também por ser a ferramenta mais utilizada nas comunidades de desenvolvedores. Esta ferramenta possui um manancial de recursos essenciais para desenvolver sistemas orientados a aspectos. Existem quatro conceitos fundamentais da orientação a aspectos, que devem ser abordados, pois, através do entendimento desses conceitos, é que o desenvolvimento de sistemas orientado a aspectos, torna-se facilitado. Alguns desses conceitos exige uma grande curva de aprendizado, mas, todo o esforço será recompensado através de uma melhor produtividade, manutenabilidade facilitada e um alto grau de reusabilidade. Segundo (JUNIOR; WINCK, 2006, pg. 47 – 49) os quatros conceitos fundamentais da orientação a aspectos são: a) Adendo(advices): é composto por duas partes, o ponto de atuação e o código que será executado quando ocorrer o ponto de junção definido na
  29. 29. 29 primeira parte. É um mecanismo bastante similar a um método, cuja função é declarar o código que deve ser executado antes, após ou durante a cada ponto de junção. b) Aspecto(aspect): é um mecanismo para agrupar fragmentos de código referentes aos componentes não funcionais em um único módulo. Ou seja, estes interesses não inerentes ao negócio, são agrupados em aspectos, evitando-se assim o código espalhado e entrelaçado. c) Pontos de Atuação (pointcuts): são as regras criadas pelo programador para especificar eventos que serão atribuídos aos pontos de junção, ou seja, definem os comportamentos do aspecto. É no ponto de atuação que os pontos de junção para um determinado inteesse são agrupados. d) Pontos de Junção (join points): são locais bem definidos da execução de um programa, como por exemplo, uma chamada a um método ou a ocorrência de uma exceção. A partir deles é que são criadas as regras impostas pelos pontos de atuação. São pontos relacionados com os interesses sistêmicos, como o de persistência, onde o aspecto irá atuar através dos pontos de atuação. Diante do que foi exposto, esta nova abordagem de progamar interesses de forma a agrupá-los em aspectos, torna o desenvolvimento de sistemas mais produtivo, fácil de manter e torna o reuso facilitado. Os benefícios da orientação a aspectos é evidente no desenvolvimento de sistemas complexos, visto que, nestes tipos de sistemas, geralmente ocorre a implementação de muitos interesses ortogonais, que ao ser utilizado a orientação a aspectos, tais interesses serão agrupados em suas respectivas unidades funcionais, demonstrando assim o significativo valor da orientação a aspectos. Os subtópicos 2.3 e 2.4 representam, atavés de um código simples, como é que se implementa um sistema que utiliza a programação orientada a aspectos. Por ser um código simples, não fica muito claro os benefícios da orientação a aspectos, mas em sistemas complexos, que utilizam, por exemplo, os recursos de persistência, logging, auditoria ou até mesmo transações, fica evidente e claro suas vantagens.
  30. 30. 30 2.2 CÓDIGO ESCRITO EM LINGUAGEM DE COMPONENTES public class Comunicador{ public static void entrega(String mensagem) { System.out.println(mensagem); } public static void entrega(String destino, String mensagem) { System.out.println(destino + “, “ + mensagem); } } public class ExecutaComunicador { public static void main ( String args[] ) //Entrega mensagem sem especificar o destinatário Comunicador.entrega(“Vamos aprender AspectJ?”); //Entrega de mensagem em que o destinatário Leitor é especificado Comunicador.entrega(“Leitor”, “Você está se divertindo com o AspectJ?”); } 2.3 CÓDIGO ESCRITO EM LINGUAGEM DE ASPECTOS A linha em negrito representa o pointcut, a linha em negrito e sublinhada representa o ponto de junção, a linha apenas sublinhada representa o adendo. public aspect aspecto1 { pointcut entregaMensagem() : call ( * Comunicador.entrega(..)); before() : entregaMensagem( ) { System.out.print(“Ola ”); } } O respectivo código acima irá gerar como resultado as mensagens “Ola Vamos Aprender AspectJ?” e “Ola Leitor, vocë está se divertindo com o AspectJ?”. Então, como a mensagem “Ola” apareceu antes das mensagens que estão dentro do corpo dos métodos entrega() da classe Comunicador? A resposta está no fato de que o advice before() executa o código que está dentro do seu corpo antes dos pontos de junção que foram identificados no ponto de atuação entregaMensagem() . É importante, também, ressaltar que o ( * ) significa métodos que
  31. 31. 31 contenham qualquer tipo de retorno, enquanto que o ( .. ) representa métodos que contenham qualquer tipo de parâmetro.
  32. 32. 32 3 ESTUDO DE CASO APLICANDO OS CONCEITOS DE AOP E PERSISTÊNCIA Este capítulo relata um estudo caso onde foi aplicada os conceitos da programação orientada a aspectos em um sistema que está sendo desenvolvido por uma equipe de desenvolvedores que trabalham em um escritório localizado na IET incubadora, para tentar acabar com a repetição de algumas linhas de código. Antes de retratar sobre os benefícios da implementação da AOP presente neste estudo de caso, os subtópicos 3.1 e 3.2, descreverá os recursos da ferramenta hibernate e os recuros da ferramenta aspectJ, respectivamente. 3.1 RECURSOS DO HIBERNATE A ferramenta hibernate, foi desenvolvida por Christian Bauer, membro da equipde de desenvolvedores do hibernate, e por Gavin King, fundador do projeto Hibernate e líder dos desenvolvedores. Esta ferramenta é dotada de muitos componentes essenciais e primordiais para realizar a persistência automatizada e transparente, que tem o objetivo de proporcionar aos desenvolvedores, uma linguagem mais próxima da orientada a objetos e também, livrar dos códigos cansativos da codificação manual. Portanto, a arquitetura da ferramenta hibernate é formada por um conjunto de interfaces, são elas: ! Configuration; ! Criteria; ! Session; ! SessionFactory; ! Transaction; ! Query
  33. 33. 33 3.1.1 INTERFACE CONFIGURATION Um objeto deste tipo realiza as configurações iniciais do hibernate, como por exemplo, o driver do banco de dados, a senha, o usuario, o dialeto, dentre outros. Portanto, através de uma instância desse objeto que se indica como deve ser realizado o mapeamento. Para demonstrar como é criado este objeto, segue-se abaixo um exemplo: Configuration cfg = new AnnotationConfiguration(); cfg.configure(“hibernate.cfg.xml”); É utilizada a classe AnnotationConfiguration() quando for utilizado o recurso de anotações para o mapeamento objeto-relacional. 3.1.2 INTERFACES CRITERIA E QUERY São interfaces que permitem realizar consultas ao banco de dados. A interface Criteria tem um dialeto muito próximo da linguagem orientada a objetos, permitindo consultas de critérios orientados para objetos. Enquanto que a interface Query permite controlar como a consulta é executada, podendo as consultas serem escritas em HQL ( não é uma linguagem de manipulação de dados, é usada apenas para obter objetos) ou no dialeto SQL nativo do banco de dados. Abaixo se encontra exemplos de consultas por critério e consultas utilizando Query. 3.1.2.1 CONSULTA UTILIZANDO A INTERFACE CRITERIA Criteria criteria = session.createCriteria(User.class); criteria.add(Expression.like(“firstname”,”Max”)); List result = criteria.list(); Esta consulta obtém um usuário através do primeiro nome. 3.1.2.2CONSULTA UTILIZANDO A INTERFACE QUERY Query q = session.createQuery(“from User u where u.firstname = :fname”); q.setString(“fname”,”Max”); List result = q.list();
  34. 34. 34 Assim como na consulta realizada, esta também obtém o usuário através do primeiro nome, só que utilizando a interface Query. 3.1.3 INTERFACE SESSION É a interface central, entre o aplicativo e o hibernate. Este gerenciador de persistência, é responsável por iniciar uma sessão, para que sejam realizadas as operações de manipulação de objetos, presentes em seus respectivos métodos: a) save(Object): persiste um objeto para uma linha de uma tabela no banco de dados; b) saveOrUpdate(Object): inclui um objeto caso ele seja transiente ou o atualiza caso seja persistente; c) delete(Object): deleta um objeto da tabela do banco de dados. Abaixo segue um exemplo de como criar um objeto persistente dessa interface: Usuario usuario = new Usuario(); usuario.setFirstname(“Pedro”); usuario.setLastname(“da Silva”); Session session = sessions.openSession(); 3.1.4 INTERFACE SESSIONFACTORY Denominada fábrica de sessões, esta interface permite a criação de objetos Sessions. Não é peso leve, pois foi criada para ser compartilhada entre muitas threads do aplicativo, sendo, portanto, threadsafe. Por ser um objeto muito pesado, deve existir apenas uma instância sua na aplicação. Ela deve ser criada, por exemplo, durante a inicialização do aplicativo. Porém, se existerem mais de um banco de dados, será preciso uma sessionFactory para cada banco de dados. Abaixo, segue um exemplo de como é instanciado um objeto desta interface: SessionFactory = cfg.buildSessionFactory();
  35. 35. 35 3.1.5 INTERFACE TRANSACATION Esta inferface abstrai de forma transparente a aplicação dos detalhes dos diversos tipos de transações. A interface Transaction é uma API opcional. Os aplicativos do Hibernate podem escolher por não usar esta interface, em vez de gerenciar transações em seu próprio código de infra-estrutura. Uma Transaction abstrai o código do aplicativo da implementação da transação subjacente – poderia ser uma transação JDBC, uma UserTransaction JTA, ou, até mesmo, uma transação CORBA (Comom Object Request Architecture, Arquitetura do Agente de Requisição de Objetos Comum), permitindo ao aplicativo controlar limites de transação por meio de uma API consistente. Isso ajuda a manter os aplicativos do Hibernate portáveis entre os diferentes tipos de ambientes de execução e de contêineres (BAUER;KING, 2005, pg. 53). Além da já descrita arquitetra do Hibernate, outros pontos primordiais desta ferramenta devem ser explicados, para que se obtenha êxito durante todo o processo de implementação dos recursos que ela proporciona. Estes pontos elementares, serão abordados nos subtópicos 3.1.6, que fará uma breve explicação do que seja uma classe persistente, 3.1.7 que irá descrever sobre identidade de objetos e o 3.1.8 irá falar sobre um dos pontos essenciais e principais da ferramente Hibernate, que são os conceitos de objetos persistentes, transientes e destacados(detached). Outro recurso importante desta ferramenta que merece ser descrito, é o recurso de anotações(annotations), que será abordado no subtópico 3.1.9. 3.1.6 O QUE SÃO CLASSES PERSISTENTES São classes entidades que serão persistidas através das instâncias de seus objetos. O hibernate requer para a criação de classes persistentes, as seguintes características: ! A classe persistente deverá possuir um construtor sem argumentos; ! Requer também métodos de acesso getters e setters; ! E por fim, um atributo id que é o seu identificador único. Para ilustrar como é implementada uma classe persistente com essas características, abaixo segue um simples exemplo: public class Cliente{ private int id; private String nome;
  36. 36. 36 public Cliente(){ } public int getId(){ return id; } public String getNome(){ return nome; } public void setNome(String nome){ this.nome = nome; } } 3.1.7 IDENTIDADE DE OBJETOS E DE BANCO DE DADOS No desenvolvimento de sistemas que utilizam linguagem java, ao se comparar dois objetos, usando o operador de igualdade, estes serão idênticos se ocuparem a mesma posição na memória. No caso, de comparação entre Strings usando este operador, pode resultar em erros, pois, será uma verificação de posição de memória, ao invés de conteúdo. Portanto, para resolver este problema, é utilizado o método equals(), significando que dois objetos diferentes possuem o mesmo valor, ou seja, são equivalentes. Mas, ao utilizar o conceito de persistência, um novo conceito de identidade passa a existir, a identidade de banco de dados. Dois objetos são idënticos em um banco de dados se forem mapeados em uma mesma linha da tabela. Segundo (BAUER;KING, 2005, pg. 116) existem três métodos para identificar objetos: a) Identidade de objetos: os objetos são idênticos se eles ocuparem o mesmo local na memória dentro da JVM. Isso pode ser verificado usando o operador = =; b) Igualdade de objetos: os objetos são iguais se possuem o mesmo valor, como definido pelo método equals(Object o). As classes que não
  37. 37. 37 sobrepõem explicitamente este método herdam a implementação definida por java.lang.Object, o qual compara a identidade de objetos; c) Identidade do banco de dados: os objetos armazenados em um banco de dados relacional são idênticos se eles representam a mesma linha ou, equivalentemente, compartilham a mesma tabela e valor de chave primária. Então, como se procede a escolha das chaves primárias? Para responder a esta pergunta, deve-se seguir o seguintes passos: ! Informar ao hibernate sobre a estratégia utilizada para a geração de chaves primárias; ! Identificar a(s) chave(s) candidata(s) que identifica(m) unicamente uma linha de uma tabela de banco de dados. Esta(s) chave(s) devem ser única(s), não nula(s) e constante(s); ! Caso necessário, deve-se identificar as chaves naturais como chaves primárias, que são chaves com significados de negócio, como por exemplo, o cpf. Deve-se ter muito cuidado neste tipo de identificação, pois assim como na identificação das chaves candidatas, as naturais, também devem ser únicas, não nulas e constantes. 3.1.8 OBJETOS PERSISTENTES, TRANSIENTES E DESTACADOS O hibernate define três estados diferentes de objetos, que são os persistentes, transisentes e destacados. Os objetos transientes são objetos que ainda não estão associados a nenhuma linha da tabela de um banco de dados relacional. Ou seja, podem ser utilizados, e após sua destruição, ficam disponíveis para o coletor de lixo(garbage collection). Por outro lado, os objetos persistentes, são objetos que foram instanciandos pelo aplicativo e que se tornaram persistentes, através da chamada ao método save() do gerenciador de persistência. E finalmente, os objetos destacados (detached) são objetos que tiveram suas instâncias persistidas em um banco de dados relacional, mas por algum motivo, deixaram de estarem associadas a algum contexto persistente. A figura abaixo, ilustra como ocorre a transição entre esses três estados de objetos.
  38. 38. 38 Figura 7 – Estado de um objeto e suas transições Fonte: BAUER, Christian; KING, Gavin 3.1.9 ANOTAÇÕES ( ANNOTATIONS ) As anotações são metadados que aparecem no código-fonte e são ignorados pelo compilador. Elas são definidas através do símbolo @ ( arroba ). Este recurso foi incorporado no JAVA SE 5.0. O JAVA SE 5.0 suporta dois tipos de anotações: as anotações simples e as meta anotações. As simples sã usadas apenas para dar algum significado especial ao código-fonte, portanto não tem nenhuma funcionalidade. Porém, as meta anotações são utilizadas para dar algum significado funcional ao código-fonte. Então, para evitar os mapeamentos cansativos através da edição de arquivos xml, os desenvolvedores da ferramenta hibernate, anexaram o recurso de anotações ao hibernate, permitindo assim, que as classes entidades java possam ser mapeadas através das anotações, tornando o mapeamento objeto-relacional, simplificado e menos tedioso. É importante lembrar que, o mapeamento por anotações é lido em tempo de execução, na inicialização do hibernate através de reflexão. Por isso, é comum inserir as anotações sobre os métodos get/set de cada atributo para que seja possível interpretar estes métodos como uma coluna de uma tabela de um banco relacional. Segue-se abaixo uma tabela descrevendo alguns tipos de anotações para mapeamento objeto-relacional.
  39. 39. 39 @Entity Indica que a classe é um entity bean (classe entidade) a ser persistida @Id Declara o identificador da entidade. Se refere à chave primária na tabela. @Table Mapeia o nome da tabela. @Column Mapeia os atributos da classe entidade para colunas na tabela. @ManyToOne Associação “muitos para um”, define a chave estrangeira de uma tabela, tendo como referência a tabela de destino. @OneToMany Associação “um para muitos”, tendo como referência a tabela de origem. @JoinColumn Define qual é a coluna que fará a ligação entre as tabelas, onde o atributo name se refere ao nome da coluna indicado no modelo relacional. Tabela 1 – Tipos de anotações 3.2 ASPECTJ A ferramenta aspectJ é a mais utilizada nas comunidades de desenvolvedores, como também pela indústria de software. Por isso tem um alto grau de maturidade dentro do mercado de software. Esta ferramenta realiza a combinação aspectual estaticamente, ou seja, para executar o programa, antes deverá ser feita uma compilação. Durante a compilação, os códigos escritos em linguagem de componentes é combinada com os códigos escritos em linguagem de aspectos. A programação utilizando AspectJ permite criar e destruir pointcuts somente em modo estático (RESENEDE;SILVA, 2005, pg. 27). Esta ferramenta é composta de elementos essenciais para a criação de um aspecto, como foi visto, no capítulo 2 – Programação Orientada a Aspectos, e que pode ser visto de forma resumida na tabela abaixo. Pontos de junção São pontos bem definidos na execução de um programa. Pontos de atuação São responsáveis por definir e agrupar pontos de junção. Adendos Declaram o código que deve ser executado no ponto de atuação. Aspecto É a unidade central do AspectJ encapsulando os elementos que o formam. Tabela 2 – Componentes elementares do AspectJ Diante do conceito sobre pontos de junção abordado no capítulo 2, e visto de forma breve na tabela acima, pode-se chegar a conclusão de que são elementos que não existem fisicamente,
  40. 40. 40 na verdade, são apenas pontos de entrada mentalizados, como marcadores imaginários de pontos onde se deseja executar porções extras de código. Existem diversos tipos de pontos de junção, os quais estão relacionados na tabela abaixo. Tabela 3 – Tipos de pontos de junção Fonte: JUNIOR, Elidio Mendes As palavras reservadas, execution, call, get, set, staticinicialization, handler, initialization, preinitialization, adviceexecution, são designadores do ponto de atuação que provêem uma definição ao redor do ponto de junção. Existem, além destes, outros designadores, como o this, target, args, cflow, cflowbelow, withincode, within e o if. Somente identificar os pontos de junção e agrupá-los em um ponto de atuação, o aspecto não terá uma funcionalidade que irá ser executada quando o(s) ponto(s) de junção for(em) alcançado(s). Para dá funcionalidade ao aspecto, é preciso declarar um advice, que é semelhante a um método de uma classe java. Existem diferentes tipos de advices, que estão descritos na tabela abaixo. Tabela 4 – Tipos de adendos(advices) Fonte: JUNIOR, Vicente Goetten; WINCK, Diogo Vinícius
  41. 41. 41 Chega um momento durante o desenvolvimento de um sistema que é preciso modificar um sistema, seja adicionando um novo atributo a uma classe, um novo método ou até mesmo, fazer uma classe herdar outra, sem mexer no código da linguagem de componentes. Isso é realizado através da declaração intertipos (intertype declarations), um dos componentes mais importantes do AspectJ, pois através dele, a estrutura de um sistema pode ser alterada. Segundo (WINCK;JUNIOR, 2006, pg. 109 – 110) as possíveis formas de declarações entre tipos do AspectJ são: ! inclusão de membros (métodos, construtores, campos) para tipos (incluindo outros aspectos); ! inclusão de implementação concreta para interfaces; ! declaração de que tipo estende um novo ou implementa uma nova interface; ! declaração de precedência do aspecto; ! declaração de erros de compilação customizáveis ou avisos; ! conversão de exceções checadas (checked exceptions) para não checadas (unchecked). Poder modificar a estrutura de um sistema, sem ser necessário, modificar o código implementado através de uma linguagem de componentes, torna o sistema mais flexível. Esse benefício é um dos pontos chaves da orientação a aspectos, que é a escalabilidade (capacidade que um sistema tem de crescer). Vale ressaltar também, que a declaração intertipos de precedência, tem uma ampla importância, pois, por exemplo, quando é identificado que o sistema a ser desenvolvido, necessitará implementar códigos relacionados a persistência e auditoria, esses dois interesses ortogonais serão implementados em dois aspectos; um para tratar a persistência e outro para a auditoria. Portanto, declarar a precedência entre esses aspectos torna-se essencial para definir qual aspecto irá interceptar o sistema através dos seus pontos de junção definidos no ponto de atuação primeiramente.
  42. 42. 42 3.3 ESTUDO DE CASO Voltando ao estudo de caso, a equipe constatou durante o desenvolvimento com a ferramenta hibernate, que em alguns métodos estava acontecendo a repetição de linhas de códigos referentes a abrir uma sessão, iniciar uma transação e depois realizar um commit e fechar a sessão. Em outros métodos apenas se repetiam as linhas referentes a abrir uma sessão e iniciar uma transação. Para resolver este problema, a equipe liberou apenas uma parte do código, para ser aplicado o paradigma da orientação a aspectos. Para melhor ilustrar, o código sem a implementação da orientação a aspectos será descrito no subtópico 3.3.1 e o código após a aplicação dos conceitos da orientação a aspectos será descrito no subtópico 3.3.3. O subtópico 3.3.2 descreve a codificação dos aspectos. O primeiro passo, após as constações das linhas repetidas, é que deve ser implementado dois aspectos, um que irá tratar dos métodos que tem as linhas responsáveis por abrir uma sessão, iniciar uma transação e no final realiza um commit e o outro irá tratar dos métodos que tem apenas as linhas repetidas relacionadas com abrir uma sessão e iniciar uma transação. 3.3.1 CÓDIGO SEM A APLICAÇÃO DA AOP public class LocalDAO { public static void cadastraLocal(Local local) throws InsercaoIlegalException { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class) .add(Restrictions.eq("descricao", local.getDescricao()).ignoreCase()).list(); if (locais.size() >0) { throw new InsercaoIlegalException(); } session.save(local); session.getTransaction().commit(); } public static void atualizaLocal(Long id, Local novoLocal) throws InsercaoIlegalException { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Local local = (Local) session.load(Local.class, id); if (!(local.getDescricao().equalsIgnoreCase(novoLocal.getDescricao()))) { ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class). add(Restrictions.eq("descricao", novoLocal.getDescricao()).ignoreCase()).list();
  43. 43. 43 if (locais.size() >0) { throw new InsercaoIlegalException(); } } local.setDescricao(novoLocal.getDescricao()); session.getTransaction().commit(); } public static void excluiLocal(Long id) throws ExclusaoIlegalException { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Local local = (Local) session.load(Local.class, id); ArrayList<SubLocal> subLocais = listaSubLocais(id); if (subLocais.size() > 0) { throw new ExclusaoIlegalException(); } session.delete(local); session.getTransaction().commit(); } public static Local buscaLocal(Long id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Local local = (Local) session.load(Local.class, id); return local; } public static ArrayList<Local> listaLocais() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class).addOrder(Order.asc("descricao").ignoreCase()).list(); return locais; } public static ArrayList<Local> listaLocaisDescricao(String descricao) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class) .add(Restrictions.like("descricao", descricao + "%").ignoreCase()).addOrder(Order.asc("descricao").ignoreCase()).list(); return locais; } public static ArrayList<SubLocal> listaSubLocais(Long id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Local local = (Local) session.load(Local.class, id); ArrayList<SubLocal> subLocais = new ArrayList(local.getSubLocais()); return subLocais; } }
  44. 44. 44 As linhas que estão em negrito referem-se as linhas que estão se repetindo. Portanto, esses métodos que possuem estas linhas, são justamente os pontos de junção que deverão ser agrupados em um pointcut, e assim ser executado o advice responsável por realizar a funcionalidade que estas linhas repetidas implementam. 3.3.2 CÓDIGO DE IMPLEMENTAÇÃO DO ASPECTO privileged aspcet ControleSessao{ pointcut abreEFechaSessao( ): call (* void LocalDAO.*( .. ) ); before( ): abreEFechaSessao( ) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); } after( ): abreEFechaSessao( ) { session.getTransaction().commit(); } } privileged aspect ManipulacaoTabela{ pointcut manipulaTabela( ): call (* void LocalDAO.*( .. ) ); pointcut auxiliar( ): !manipulaTabela; before( ): auxiliar( ){ Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); } O primeiro aspecto controleSessao declara um ponto de atuação abreEFechaSessao( ) que irá agrupar as chamadas aos pontos de junção referentes a todos os métodos da classe LocalDAO que não retornem nenhum valor, ou seja, que seja do tipo void, não importanto o tipo de acesso ( conseguido através da utilização do curinga ( * ) ) e nem quantos e quais os tipos de parâmetros ( conseguido através da utilização do coringa ( .. ) ). Após o agrupamento dos pontos de junção no ponto de atuação, é declarado em seguida o adendo (advice) before() que irá executar as linhas contidas no seu corpo delimitado pela abertura e fechamento das chaves { } referentes a abrir uma sessão e iniciar uma transação, antes da computação do ponto de atuação. E por fim, é declarado o adendo after( ), que irá executar a linha referente a confirmação para o banco de dados da persistência através de um commit. Já o segundo aspecto ManipulacaoTabela primeiramente declara um ponto de atuação ( pointcut ) denominado manipulaTabela( ) que agrupa os métodos, da mesma forma como foi descrito no ponto de atuação abreEFechaSessao do aspecto ( aspect )
  45. 45. 45 ControleSessao. Em seguida é declarado um outro ponto de atuação, denominado auxiliar que agrupa os pontos de junção que não sejam aqueles que foram agrupados no ponto de atuação manipulaTabela. Após estas declarações, é declarado o adendo before( ) que irá executar as linhas referentes a abrir uma sessão e iniciar uma transação, antes dos pontos de junção agrupados no ponto de atuação auxiliar. Após a implementação do aspecto, será preciso retirar as linhas repetidas de seus respectivos métodos. O resultado será o código relacionando no subtópico abaixo. 3.3.3 CÓDIGO APÓS A APLICAÇÃO DO ASPECTO public class LocalDAO { public static void cadastraLocal(Local local) throws InsercaoIlegalException { ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class) .add(Restrictions.eq("descricao", local.getDescricao()).ignoreCase()).list(); if (locais.size() >0) { throw new InsercaoIlegalException(); } session.save(local); } public static void atualizaLocal(Long id, Local novoLocal) throws InsercaoIlegalException { Local local = (Local) session.load(Local.class, id); if (!(local.getDescricao().equalsIgnoreCase(novoLocal.getDescricao()))) { ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class) .add(Restrictions.eq("descricao", novoLocal.getDescricao()).ignoreCase()).list(); if (locais.size() >0) { throw new InsercaoIlegalException(); } } local.setDescricao(novoLocal.getDescricao()); } public static void excluiLocal(Long id) throws ExclusaoIlegalException { Local local = (Local) session.load(Local.class, id); ArrayList<SubLocal> subLocais = listaSubLocais(id); if (subLocais.size() > 0) { throw new ExclusaoIlegalException(); } session.delete(local); } public static Local buscaLocal(Long id) { Local local = (Local) session.load(Local.class, id); return local; } public static ArrayList<Local> listaLocais() { ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class).addOrder(Order.asc("descricao").ignoreCase()).list(); return locais;
  46. 46. 46 } public static ArrayList<Local> listaLocaisDescricao(String descricao) { ArrayList<Local> locais = (ArrayList<Local>) session.createCriteria(Local.class) .add(Restrictions.like("descricao", descricao + "%").ignoreCase()).addOrder(Order.asc("descricao").ignoreCase()).list(); return locais; } public static ArrayList<SubLocal> listaSubLocais(Long id) { Local local = (Local) session.load(Local.class, id); ArrayList<SubLocal> subLocais = new ArrayList(local.getSubLocais()); return subLocais; } } Como se pode ver, após a aplicação do aspecto, o código referente as linhas que estavam se repetindo em diversos métodos da classe LocalDAO, ficaram centralizadas nos respectivos aspectos, tornando o código mais enxuto, modularizado e até mesmo, mais fácil de manter, pois qualquer alteração referente as linhas repetidas serão realizadas nos aspectos, sem ser preciso mexer no código implementado na linguagem de componentes ( requisitos funcionais ou unidade de negócio ).
  47. 47. 47 CONCLUSÃO É fato que, cumprir os prazos descritos no projeto do software, torna-se um fator essencial para que as empresas de software obtenham sucesso em um mercado totalmente globalizado e concorrido. Essa é a idéia principal por trás da aplicação da orientação a aspectos juntamente com a persistência automatizada, proporcionar uma nova filosfia de desenvolvimento que tem por objetivo, tornar a codificação mais simples, o sistema mais flexível e consequentemente a fabricação do software mais produtiva. Para tanto, é preciso investir no treinamento da equipe para se adaptar a essas duas abordagens. A curva de aprendizado pode ser alta, mas o retorno do investimento vale muito a pena. Pois, a longo prazo, a empresa desenvolvedora de software terá vantagens relacionadas ao custo/benefícios. Vantagens essas proporcionadas por um sistema com alto grau de reusabilidade, manutenabilidade facilitada e principalmente escalabilidade. Reusabilidade e manutenabilidade, porque o código ficará mais modularizado, enxuto. Pois, com a utilização da AOP, cada módulo será responsável por uma certa funcionalidade do sistema. Escalabilidade, justificada pelo fato de que a estrutura do sistema, pode ser alterada com a aplicação da AOP, e assim, o sistema poderá crescer sem ser preciso mexer no código já implementado. Outro fator, também muito importante, é que com a aplicação da persistência automatizada, a codificação SQL se torna mais produtiva e menos propensa a erros, sobrando ainda tempo para efetuar otimizações. Como foi visto no estudo de caso, após a criação dos aspectos, as linhas repetidas foram retiradas e implementadas uma única vez dentro dos aspectos. Como benefício, foi a diminuição de linhas de código e uma melhor modularização do sistema. Portanto, diante do que foi exposto nos capítulos anteriores, as chances dessas duas abordagens juntas, se consagrar são relativamente grandes, bastando apenas que a comunidade
  48. 48. 48 desenvolvedora e a indústria de software, e principalmente, nas faculdades e universidades começarem a desenvolver projetos e até mesmo comercializar.
  49. 49. 49 REFERÊNCIAS BIBLIOGRÁFICAS BAUER, Christian; KING, Gavin. Hibernate em Ação. 2. ed. Rio de Janeiro: Ciência Moderna, 2005. FERNANDES, Raphaela Galhardo;LIMA, Gleydson de A. Ferreira. Hibernate com Anotações. Natal, 2007. FERREIRA, João Eduardo; TAKAI, Osvaldo Kotaro. Persistência de Objetos. 2005. FURTADO, André Wilson Brotto. Identificando Oportunidades de Programação Orientada a Aspectos no Desenvolvimento de Jogos. Universidade Federal de Pernambuco. 2004. JUNIOR, Elidio Mendes. Aplicação da Programação Orientada a Aspectos na Implementação de Registros de Transações Bancárias. Escola Politécnica da Universidade de São Paulo. 2007. JUNIOR, Vicente Goetten; WINCK, Diogo Vinícius. AspectJ: programação orientada a aspectos com java. 1. ed. São Paulo: Novatec, 2006. MENDONÇA, Nabor C.;SILVA, Clayton F. Uma Abordagem para Integrar Aspectos e Serviços Web. Universidade de Fortaleza. Ceará, 2004. MONTEIRO, Elaine da Silva; FILIPAKIS, Cristina D’ornellas. Um Exemplo da Modelagem de um Domínio Bancário Utilizando a Orientação a Aspectos. Laboratório de Banco de Dados e Engenharia de Software – Centro Universitário Luterano de Palmas. 2004. RAINONE, Flávia. Programação Orientada a Aspectos Dinâmica. São Paulo, 2005. RESENDE, Antônio Maria Pereira de; SILVA, Claudney Calixto da. Programação Orientada a Aspectos em Java: desenvolvimento de software orientado a aspectos. 1. ed. Rio de Janeiro: Brasport, 2005. SILVA, Lyrene Fernandes da. Uma Estratégia Orientada a Aspectos para Modelagem de Requisitos. Rio de Janeiro, 2006.
  50. 50. 50 SILVA, João Carlos da; et al. Estratégias de Persistência em Software Orientado a Objetos: definição e implementação de um framework para mapeamento objeto-relacional. Juiz de Forma, Minas Gerais.
  51. 51. 51
  52. 52. 52

×