SlideShare ist ein Scribd-Unternehmen logo
1 von 52
Downloaden Sie, um offline zu lesen
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
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
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
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é 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
@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
! @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
! 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
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
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
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
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
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
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
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
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
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 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
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
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
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
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
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
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
@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
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
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
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
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
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
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
}
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
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
desenvolvedora e a indústria de software, e principalmente, nas faculdades e universidades
começarem a desenvolver projetos e até mesmo comercializar.
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
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
52

Weitere ähnliche Inhalte

Was ist angesagt?

Javascript
JavascriptJavascript
JavascriptTiago
 
Plano de projeto de software para o sistema MEA - monitoraemto de eventos ad...
Plano de projeto de software para o sistema  MEA - monitoraemto de eventos ad...Plano de projeto de software para o sistema  MEA - monitoraemto de eventos ad...
Plano de projeto de software para o sistema MEA - monitoraemto de eventos ad...Lucas Aquino
 
Programacao cpp
Programacao cppProgramacao cpp
Programacao cppTiago
 
Usabilidade da interfaces de dispositivos móveis
Usabilidade da interfaces de dispositivos móveisUsabilidade da interfaces de dispositivos móveis
Usabilidade da interfaces de dispositivos móveismarcelonovo
 
Amm advpl - 01 básico-rev01 2
Amm   advpl - 01 básico-rev01 2Amm   advpl - 01 básico-rev01 2
Amm advpl - 01 básico-rev01 2Marcelo Pacheco
 
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Vagner Nogueira
 
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃO
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃOLIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃO
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃOOs Fantasmas !
 

Was ist angesagt? (11)

Javascript
JavascriptJavascript
Javascript
 
Plano de projeto de software para o sistema MEA - monitoraemto de eventos ad...
Plano de projeto de software para o sistema  MEA - monitoraemto de eventos ad...Plano de projeto de software para o sistema  MEA - monitoraemto de eventos ad...
Plano de projeto de software para o sistema MEA - monitoraemto de eventos ad...
 
Manual excel 2007[1]
Manual excel 2007[1]Manual excel 2007[1]
Manual excel 2007[1]
 
Programacao cpp
Programacao cppProgramacao cpp
Programacao cpp
 
Monografia bpm
Monografia bpmMonografia bpm
Monografia bpm
 
Usabilidade da interfaces de dispositivos móveis
Usabilidade da interfaces de dispositivos móveisUsabilidade da interfaces de dispositivos móveis
Usabilidade da interfaces de dispositivos móveis
 
Amm advpl - 01 básico-rev01 2
Amm   advpl - 01 básico-rev01 2Amm   advpl - 01 básico-rev01 2
Amm advpl - 01 básico-rev01 2
 
Apostila excel sandro unipac
Apostila excel   sandro unipacApostila excel   sandro unipac
Apostila excel sandro unipac
 
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
Modelagem de Base de Conhecimentos Baseada em Ontologia Estudo de Caso em Rec...
 
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃO
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃOLIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃO
LIVRO PROPRIETÁRIO - FUNDAMENTOS DE SISTEMA DA INFORMAÇÃO
 
Advpl completo
Advpl completo Advpl completo
Advpl completo
 

Ähnlich wie Tcc aop-e-persistencia

sistemas_operacionais-livro.pdf
sistemas_operacionais-livro.pdfsistemas_operacionais-livro.pdf
sistemas_operacionais-livro.pdfJoelManuel8
 
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...marcelobeckmann
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaJooMarcos614503
 
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...Mauricio Volkweis Astiazara
 
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...Igor Costa
 
Linguagem c
Linguagem cLinguagem c
Linguagem cTiago
 
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...Elaine Cecília Gatto
 
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...Elaine Cecília Gatto
 
Livro analise de dados amostrais complexos
Livro analise de dados amostrais complexosLivro analise de dados amostrais complexos
Livro analise de dados amostrais complexosDiogo Freire
 
Apostila Pesquisa operacional
Apostila Pesquisa operacionalApostila Pesquisa operacional
Apostila Pesquisa operacionalPamella Campos
 
Plano de projeto: Bichos do Campus na Web
Plano de projeto: Bichos do Campus na WebPlano de projeto: Bichos do Campus na Web
Plano de projeto: Bichos do Campus na WebJorge Roberto
 
Python gtk
Python gtkPython gtk
Python gtkTiago
 
Relatorio tecnico sobre os fatores motivadores em equipe open source
Relatorio tecnico sobre os fatores motivadores em equipe open sourceRelatorio tecnico sobre os fatores motivadores em equipe open source
Relatorio tecnico sobre os fatores motivadores em equipe open sourceDanilo Monteiro
 

Ähnlich wie Tcc aop-e-persistencia (20)

monografia_andre_paro
monografia_andre_paromonografia_andre_paro
monografia_andre_paro
 
sistemas_operacionais-livro.pdf
sistemas_operacionais-livro.pdfsistemas_operacionais-livro.pdf
sistemas_operacionais-livro.pdf
 
Poojava
PoojavaPoojava
Poojava
 
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...
Dissertation: Genetic Algorithms as a pre processing strategy for imbalanced ...
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com Java
 
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...
Sistema Imunológico Artificial para Predição de Fraudes e Furtos de Energia E...
 
Estrutura de dados 3
Estrutura de dados 3Estrutura de dados 3
Estrutura de dados 3
 
Introdução a estrutura de dados
Introdução a estrutura de dadosIntrodução a estrutura de dados
Introdução a estrutura de dados
 
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...
Plano de Projeto de Software para o desenvolvimento do SIGE (Sistema de Geren...
 
Estruturas dados
Estruturas dadosEstruturas dados
Estruturas dados
 
Estruturas dados
Estruturas dadosEstruturas dados
Estruturas dados
 
Linguagem c
Linguagem cLinguagem c
Linguagem c
 
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
 
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
EXPLORANDO CORRELAÇÕES PARA O PARTICIONAMENTO DO ESPAÇO DE RÓTULOS EM PROBLEM...
 
Manual getic 23-out_09
Manual getic 23-out_09Manual getic 23-out_09
Manual getic 23-out_09
 
Livro analise de dados amostrais complexos
Livro analise de dados amostrais complexosLivro analise de dados amostrais complexos
Livro analise de dados amostrais complexos
 
Apostila Pesquisa operacional
Apostila Pesquisa operacionalApostila Pesquisa operacional
Apostila Pesquisa operacional
 
Plano de projeto: Bichos do Campus na Web
Plano de projeto: Bichos do Campus na WebPlano de projeto: Bichos do Campus na Web
Plano de projeto: Bichos do Campus na Web
 
Python gtk
Python gtkPython gtk
Python gtk
 
Relatorio tecnico sobre os fatores motivadores em equipe open source
Relatorio tecnico sobre os fatores motivadores em equipe open sourceRelatorio tecnico sobre os fatores motivadores em equipe open source
Relatorio tecnico sobre os fatores motivadores em equipe open source
 

Tcc aop-e-persistencia

  • 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 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 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 Dedico este trabalho: à minha mãe, Maria Aparecida; à minha namorada, Thaysa; ao meu primo, Minervo
  • 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 @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 ! @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 ! 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 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 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 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 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 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 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 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 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 contenham qualquer tipo de retorno, enquanto que o ( .. ) representa métodos que contenham qualquer tipo de parâmetro.
  • 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 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 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 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 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 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 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 @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 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 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 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 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 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 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 } 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 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 desenvolvedora e a indústria de software, e principalmente, nas faculdades e universidades começarem a desenvolver projetos e até mesmo comercializar.
  • 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 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
  • 52. 52