Padrões Arquiteturais para o Acesso a Banco de Dados
Transcript of Padrões Arquiteturais para o Acesso a Banco de Dados
Padrões Arquiteturais para o Acesso a Banco de Dados
Instituto de Matemática e EstatísticaUniversidade de São Paulo
Kelly Rosa [email protected]
Departamento de Ciência da Computação
2
Primórdios das Arquiteturasem Camadas
● Anos 90 – primeiros sistemas “em camadas”– Apenas 2 camadas: cliente – servidor– Cliente = interface com o usuário – Servidor = BD relacional
● Ferramentas para o desenvolvimento dos clientes: Visual Basic, PowerBuilder, Delphi– Facilitavam a construção de aplicações de manipulação
intensiva de dados– Permitiam que controles fossem arrastados para uma área
de desenho da interface e que depois fossem conectados a elementos do BD
3
Problema da Arquitetura Cliente-Servidor
● Onde embutir a lógica do domínio?
– Regras de negócio, validações, cálculos, etc.● Geralmente, ficavam no código do cliente
– Lógica era embutida nas telas da interface– Precisava ser replicada em diferentes telas →
manutenção difícil
4
Problema da Arquitetura Cliente-Servidor
● Alternativa: embutir lógica do negócio no servidor → no BD, por meio de stored procedures
● Essa estratégia não é muito bem aceita devido as características das linguagens para stored procedures
– São mais pobres que linguagens de programação convencionais
– Não são padronizadas; são específicas para um SGBD e impedem que o BD possa ser “portado” a um baixo custo
5
Solução: Arquitetura em 3 Camadas
● Contexto de criação: disseminação das linguagens de programação orientadas a objetos e o crescimento da Web
● Componentes da arquitetura em 3 camadas:
– Camada de apresentação: para as interfaces com o usuário
– Camada de domínio: para a lógica do negócio
– Camada de dados: comunicação com os bancos de dados
6
Camada de Apresentação
● Trata da interação entre o usuário e o software
● Principais responsabilidades:
– Mostrar informações– Interpretar comandos do usuário e disparar as ações
correspondentes nas outras duas camadas ● A interação com os usuários pode ser por meio de diferentes tipos
de interface:
– Linha de comando, interface gráfica, interface HTML
– Uma mesma aplicação pode ter mais de uma interface com usuário
● As requisições vêm na forma de cliques de mouses, teclas digitadas, requisições HTTP
7
Camada de Domínio
● Faz o trabalho que é específico para o domínio de aplicação sendo tratado:
– cálculos baseados em dados de entrada ou dados armazenados
– validação de dados que vêm da camada de apresentação
– escolha da lógica e de fontes de dados em função dos comandos recebidos via camada de apresentação
– processamento e formatação dos dados recebidos da camada de fontes de dados antes de repassá-los à camada de apresentação
8
Camada de Dados
● Um dos principais papéis da camada de dados é estabelecer a comunicação entre o sistema e os BDs
● Existem diferentes padrões arquiteturais no que se refere à forma como a lógica do domínio “conversa” com os BDs
– Padrões: são soluções comuns para problemas recorrentes
● A escolha de uma arquitetura para a comunicação com o BD é uma etapa crítica no projeto de um sistema, já que é algo muito complicado de se refatorar depois
9
Padrões Arquiteturais para a Camada de Dados
● Recomendado: separar código em SQL do código da lógica do negócio, colocando-os em classes diferentes
– Vantagem dessa separação: código SQL concentrado em um só lugar evita replicação, facilita a manutenção, etc.
● Organização das classes pode se basear na estrutura do BD
– Ex.: uma classe por tabela → gateway para a tabela
11
Tipos de Gateways para Acesso ao BD
● Gateway de linha de dados (row data gateway) – um objeto que atua como um gateway para uma única tupla em uma fonte de dados
– Existe uma instância por tupla– Essa abordagem combina bem com
orientação a objetos (cada tupla pode corresponder a um objeto)
12
Tipos de Gateways para Acesso ao BD
● Gateway de tabela de dados (table data gateway) – um objeto que atua como gateway para uma relação (tabela ou visão) do BD
– Uma única instância (do tipo conjunto de registros) manipula todas as tuplas da relação
– Bastante usado para devolver recordsets – uma estrutura de dados genérica para tabelas e linhas (que imita a estrutura tabular dos BDs relacionais). Ela existe em diversas linguagens de programação e costuma ser usada em diferentes partes de uma aplicação
13
Gateway de Linha de Dados
● Um gateway de linha de dados é um objeto com uma estrutura semelhante à tupla armazenada no BD, mas que pode ser acessada por meio dos mecanismos regulares de uma linguagem de programação
● Todos os detalhes do acesso a fonte de dados ficam escondidos atrás dessa interface
https://martinfowler.com/eaaCatalog/rowDataGateway.html
14
Gateway de Tabela de Dados
● Um gateway de tabela de dados armazena todo o SQL para acessar uma única relação: seleção, inserção, atualização e remoção
– Outros códigos chamam seus métodos para todas as interações com o banco de dados
https://martinfowler.com/eaaCatalog/tableDataGateway.html
15
Um Parênteses sobre Objetos...
Em linguagens de programação OO:● Objeto é uma instância de uma classe
– Objetos têm estados (= valores para seus atributos)– Objetos têm comportamentos (= métodos)
● Modelo de objetos é uma coleção de todas as definições de classes de uma aplicação
● As classes podem representar:– Elementos de interface do usuário– Recursos do sistema– Eventos da aplicação– Abstrações dos conceitos de negócio
16
Objetos de Negócio
● Exemplos de objetos que abstraem conceitos de negócio:– Num sistema de processamento de pedidos:
● Cliente, Pedido e Produto
– Numa aplicação financeira● Cliente, Conta, Crédito, Débito
● Esses objetos modelam o domínio do negócio onde a aplicação específica irá operar → são chamados de Modelo de Domínio
17
Padrão Modelo de Domínio
● Um objeto do modelo de domínio incorpora tanto dados quanto comportamento
● Um modelo de domínio cria uma rede de objetos interconectados, onde cada objeto representa alguma entidade significativa
– Que pode ser tão grande quanto uma corporação ou tão pequeno quanto uma linha em um formulário de pedido
https://martinfowler.com/eaaCatalog/domainModel.html
18
Persistência de Objetos
● Os objetos do modelo de domínio representam os principais estados e comportamentos da aplicação
● Geralmente, esses objetos:
– São compartilhados por vários usuários simultaneamente – São armazenados e recuperados entre as execuções da
aplicação● Persistência de objetos – capacidade desses objetos de
“sobreviverem” além do tempo de execução da aplicação
● Objetos podem ser persistidos em diferentes tipos de fontes de dados (data sources)
– A persistência não é exclusividade dos objetos de domínio (mas é um requisito mais frequente para eles)
19
Mapeamento de Objetos para Bancos de Dados
● Para persistência dos objetos em BDs, é preciso fazer um mapeamento– Mapeamento objeto-relacional (ORM – Object-Relational Mapping)– Mapeamento objeto-documento (ODM – Object-Document Mapping)– Mapeameto objeto-[outros tipos de BDs NoSQL]
● Na implementação do mapeamento, são usados padrões arquiteturais para camada de dados, como os gateways
● Existem ferramentas para o mapeamento automático– Geração automática da estrutura do BD a partir das classes de modelo de
domínio– Geração automática das classes a partir da estrutura do BD– Definição manual de mapeamentos entre BDs e classes já existentes
● Feita por meio de anotações em classes ou arquivos de configuração
20
Padrões de Mapeamentopara Modelo de Domínio
● Em aplicações que usam modelo de domínio, outras opções de mapeamento podem ser mais apropriadas
– Dependendo do modelo de domínio e da estrutura da fonte de dados, os gateways podem ter complexidade demais ou de menos
● Exemplos de padrões de mapeamento usados com modelo de domínio:
– Active Record
– Data Mapper
21
Active Record
● Em aplicações com modelo de domínio simples:
– Estrutura do modelo de domínio se assemelha bastante à estrutura do BD, com uma classe do domínio por tabela do BD
– Objetos do domínio possuem lógica de negócio de complexidade moderada
● Nesse contexto, é viável que cada objeto do domínio se ocupe pelo carregamento e pelo salvamento de dados no BD → esse padrão de arquitetura é chamado de Registro Ativo (Active Record)
22
Active Record
● Um objeto que encapsula uma tupla de uma relação do BD, encapsula o acesso ao BD e adiciona lógica de domínio aos dados
● Um objeto carrega tanto dados quanto comportamento
● A maior parte dos dados é persistente e precisa ser armazenada em um BD
https://martinfowler.com/eaaCatalog/activeRecord.html
23
O Padrão Active Record “na Prática”
● Ruby On Rails (Ruby)
● Django (Python)
● Eloquent/Laravel (PHP)
● ActiveJDBC (Java)
● DBIx::Class (Perl)
● …
24
Mas o Active Record Não É Suficiente Quando...
● A lógica de domínio é mais complicada → modelo de domínio complexo
● Não há um mapeamento 1-para-1 entre as classes do modelo e as tabelas do BD
● Existe a necessidade de se testar a lógica de negócio sem que o acesso ao BD seja feito o tempo todo
→ Nesses casos, nem mesmo a indireção do padrão Gateway é suficiente para lidar com a complexidade
● Alternativa: padrão Data Mapper
25
Data Mapper
● É uma camada de mapeadores que transferem dados entre objetos de domínio e um BD, mantendo-os independentes entre si
● Essa é a arquitetura de mapeamento mais complicada, mas que garante isolamento entre as duas camadas
– Tanto o modelo de domínio quanto o de BD podem variar sem que um afete o outro
https://martinfowler.com/eaaCatalog/dataMapper.html
26
O Padrão Data Mapper “na Prática”
● MyBatis, para Java
● SQLAlchemy, para Python
● Ruby Object Mapper (ROM), para Ruby
● Doctrine, para PHP
● ...
27
Padrão Data Acess Object (DAO)
● Data Acess Object (DAO) – objeto de acesso aos dados● Muito usado em aplicações Java
– Origem: “Core J2EE Patterns”● “O DAO abstrai e encapsula todos os acessos a uma fonte de
dados. Ele gerencia a conexão com a fonte de dados para obter e armazenar dados”
● Provê uma interface abstrata para algum tipo de mecanismo de persistência– SGBDRs, SGBOO, XML, etc.– Provê operações sobre os dados sem expor detalhes de
implementação da fonte de dados● Equivale ao padrão Data Mapper!
28
DAO – Diagrama de Classes (UML)
● BusinessObject – objeto “cliente”, que requisita o acesso aos dados
● DataAcessObject – abstrai a implementação do acesso aos dados para o BusinessObject
● DataSource – representa a implementação de uma fonte de dados
● TransferObject – usado para “carregar” dados (obtidos da fonte de dados) para o BusinessObject
https://www.oracle.com/java/technologies/dataaccessobject.html
29
DAO – Diagrama de Sequência (UML)
https://www.oracle.com/java/technologies/dataaccessobject.html
30
Fábrica de DAOsDiagrama de Classes (UML)
● Quando o tipo de BD usado na persistência não muda de um business object para outro, pode-se usar o padrão de projeto Factory Method (construtor virtual) para criar os diferentes DAOs de que a aplicação precisa, como mostrado no diagrama ao lado
https://en.wikipedia.org/wiki/Factory_method_pattern
https://www.oracle.com/java/technologies/dataaccessobject.html
31
Fábrica Abstrata de DAOs
● Quando o tipo de BD usado na persistência pode mudar de uma implementação para outra, pode-se usar o padrão de projeto Abstract Factory, como mostrado no diagrama do próximo slide
● Este padrão permite a criação de famílias de objetos relacionados por meio de uma única interface e sem que a classe concreta seja especificada
https://en.wikipedia.org/wiki/Abstract_factory_pattern● Nesta estratégia, usa-se um objeto da fábrica DAO abstrata para construir vários
tipos de fábricas DAO concretas, cada fábrica apoiando um tipo diferente de implementação de persistência (ex., em BD relacional, em XML, em BD orientado a objetos)
● Com uma fábrica DAO concreta para um determinado tipo de implementação de persistência, produz-se os DAOs desse tipo de implementação
● Um DAOs pode estender e implementar uma classe de base genérica, que descreve os requisitos do business object a que ele corresponde. Um DAO concreto cuida da conexão com o BD e da manipulação de dados para o seu business object.
32
Fábrica de DAOsDiagrama de Classes (UML)
https://www.oracle.com/java/technologies/dataaccessobject.html
fábrica DAO abstrata
fábrica DAO concretapara um dado tipo de BD
DAO concreto de um dado tipo de business object, para um dado tipo de BD
DAO abstrato para um dado tipo de business object
33
Fábrica de DAO – Diagrama de Sequência
https://www.oracle.com/java/technologies/dataaccessobject.html
34
Exemplo de uma Implementação Simples do DAO em Java
● Ver arquivos do Exemplo 2, disponibilizado com o material da aula– Adaptado do exemplo de DAO dado em:
http://www.caelum.com.br/apostila-java-web/bancos-de-dados-e-jdbc/ ● No exemplo, há apenas uma classe no Modelo de Domínio – a classe
Contato –, que possui como atributos nome, e-mail, endereço e data de nascimento. Os objetos de Contato são persistidos em uma tabela de um BD relacional
– O próximo slide mostra a classe Contato e a tabela correspondente– A implementação do DAO para Contato está dentro do diretório
chamado “BD” no código fonte disponibilizado– Além da classe ContatoDAO, o diretório contém a classe
FabricaDeConexao, que implementa o padrão Fábrica para a criação de conexões com o BD. Ele será mostrado a seguir.
35
Exemplo: Implementando os Padrões em Java
create table contatos (
id serial,
nome VARCHAR(255),
email VARCHAR(255),
endereco VARCHAR(255),
dataNascimento DATE,
primary key (id)
);
public class Contato {
private Long id;
private String nome;
private String email;
private String endereco;
private Calendar dataNascimento;
// métodos get e set para id, nome, email, ...
public String getNome() {
return this.nome; }
public void setNome(String novo) {
this.nome = novo; }
public String getEmail() {
return this.email; }
public void setEmail(String novo) {
this.email = novo; }
...
● Classes do domínio → implementadas como classes em Java que possuem um construtor sem argumentos e métodos get e set para o acesso aos atributos
● Exemplo para entidade Contato:
36
Um Padrão para Controlar as Conexões com o BD: Fábrica de Conexões
● Uma fábrica de conexões se ocupa da criação de conexões com o BD– Sempre que solicitada, ela devolve uma conexão com o BD– Todas as conexões usadas na aplicação devem ser criadas por meio dela
● Vantagens de uma fábrica de conexões:– Oculta os detalhes da criação da conexão (localização do BD,
informações de autenticação, configurações de conexão, etc.)● Facilita a manutenção, por centralizar esses detalhes em um só lugar
do código da aplicação– Pode fazer pooling de conexões (para diminuir o volume de operações de
criação e fechamento de conexões – essas operações consomem tempo)● Ao invés de devolver uma conexão nova a cada nova requisição, a
fábrica pode devolver uma conexão que já estava aberta, mas que não estava mais em uso
● A fábrica gerencia o pool de conexões abertas
37
Um Padrão para Controlar as Conexões com o BD: Fábrica de Conexões
● Exemplo em Java + JDBC:public class FabricaDeConexao {
public Connection obterConexao() {
try {
return DriverManager.getConnection(
"jdbc:postgresql://meuservidor.br:23001/bd_teste",
"usuario","senha");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
● Sempre que uma nova conexão for necessária:Connection con = new FabricaDeConexao().obterConexao();
38
Fechando uma Conexão
public static void main(String[] args) throws SQLException {
Connection con = null;
try {
con = new FabricaDeConexao().obterConexao();
// faz algumas operações sobre a conexão
// que podem gerar exceções (SQLException)
catch(SQLException e) {
System.out.println(e);
} finally {
con.close(); // A conexão será fechada mesmo
} // em caso de exceção no bloco “try”
}
39
Fechando uma Conexão
● É possível se beneficiar da estrutura try-with-resource
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
● Nesse tipo de “try”, é possível declarar e inicializar objetos que implementam java.lang.AutoCloseable– Ao término do “try”, o close do objeto será invocado
automaticamente● Exemplo:
try (Connection con = new FabricaDeConexao().obterConexao()){
// faz um monte de operações sobre a conexão
// que podem gerar exceções
catch(SQLException e) {
System.out.println(e);
}
40
Exemplo de Implementação do Data Mapper em Java
● Um exemplo de implementação do Data Mapper foi disponibilizado com o material da aula (arquivos do Exemplo 3)
– Baseado nos exemplos contidos no livro “Patterns of Enterprise Architecture”
– Adaptado do código em:
https://github.com/asakichy/PofEAA
● Nesse exemplo, há apenas uma classe de domínio – a Person –, que tem como atributos firstName, lastName e numberOfDependents
● Além do Data Mapper, o código do Exemplo 3 exemplifica a implementação do padrão Identity Map
https://martinfowler.com/eaaCatalog/identityMap.html
41
● Principais
– Row Data Gateway
– Table Data Gateway
– Data Mapper
– Active Record
● Auxiliares
– Unit of Work
– Identity Map
– Lazy Load
Lista (Incompleta) dos Padrões Arquiteturais para Camada de Dados
● Mapeamento de relacionamentos
– Identity Field
– Foreign Key Mapping
– Association Table Mapping
http://martinfowler.com/eaaCatalog/
42
“Lição de Casa” - I
● Ler (no site ou no livro do Martin Fowler) sobre os padrões:– Unit of Work – “Maintains a list of objects affected by a business
transaction and coordinates the writing out of changes and the resolution of concurrency problems.”
https://martinfowler.com/eaaCatalog/unitOfWork.html
– Identity Map – “Ensures that each object gets loaded only once by keeping every loaded object in a map.”
https://martinfowler.com/eaaCatalog/identityMap.html
– Lazy Load – “An object that doesn't contain all of the data you need but knows how to get it.”
https://martinfowler.com/eaaCatalog/lazyLoad.html
43
“Lição de Casa” - II
● Ler (no site ou no livro do Martin Fowler) sobre os padrões:
– Identity Field – “Saves a database ID field in an object to maintain identity between an in-memory object and a database row.”
https://martinfowler.com/eaaCatalog/identityField.html
– Foreign Key Map – “Maps an association between objects to a foreign key reference between tables.”
https://martinfowler.com/eaaCatalog/foreignKeyMapping.html
– Association Table Mapping – “Saves an association as a table with foreign keys to the tables that are linked by the association.”
https://martinfowler.com/eaaCatalog/associationTableMapping.html
44
Referências Bibliográficas
● Livro: “Patterns of Enterprise Application Architecture” (2012), de Martin Fowler,
– Capítulo 3 – “Data Source Architectural Patterns” está disponível online:
http://www.informit.com/articles/article.aspx?p=1398618
– Resumo dos padrões:
http://martinfowler.com/eaaCatalog/
● “Core J2EE Patterns - Data Access Object”
http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
● Apostila da Caelum – “Banco de Dados e JDBC”
http://www.caelum.com.br/apostila-java-web/bancos-de-dados-e-jdbc/
● Slides do prof. João Eduardo Ferreira sobre persistência:
http://www.ime.usp.br/~jef/persistencia.pdf