1. Implementando Enterprise
Patterns em PHP
Pablo Dall'Oglio
Adianti Solutions
www.adianti.com.br
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
2. CHANGELOG
2008 :: FISL9.0
Enterprise Patterns em PHP;
2009 :: PHPMS
Enterprise Patterns em PHP;
2009 :: GOPHP
Enterprise Patterns em PHP;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
2
3. Patterns
O que são Design Patterns ?
“Um pattern descreve um problema que ocorre com
freqüência em nosso ambiente, e então explica a essência
da solução para este problema, de forma que tal solução
possa ser utilizada milhões de outras vezes...”
Christopher Alexander (1936 arquiteto)
ponte estaiada
ponte de viga
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
ponte em arco
3
4. Observações
Padrões são descobertos, não inventados. Na maioria
das vezes, já utilizamos algum padrão, sem saber;
O conhecimento dos padrões nos leva a distinguir em
quais situações utilizá-los;
Não existe padrão melhor ou pior, existem padrões que
são mais indicados para determinadas situações;
Um padrão não é uma solução pronta;
Os códigos a seguir são apenas UMA das formas de
implementar os patterns, provavelmente não a melhor,
visto que aqui o enfoque é DIDÁTICO :-)
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
4
5. Observações
Christopher Alexander utilizou o termo pattern
inicialmente em 1977 aplicado à arquitetura;
Kent Beck e Ward Cunningham começaram a aplicar
patterns à programação em 1987;
Design Patterns tornaram-se populares após o livro de
Gamma em 1994:
Design Patterns: Elements of Reusable ObjectOriented Software;
Após, outras publicações seguiram, focadas em padrões
para concorrência em sistemas distribuídos, em
integração de aplicações, dentre outros.
Martin Fowler desenvolve um trabalho focado em
aplicações corporativas em 2002:
Patterns of Enterprise Application Architecture.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
5
6. Mapeamento Objeto-Relacional (Persistência)
• Persisência significa continuar a existir, perseverar, durar
longo tempo ou permanecer;
• A possibilidade dos objetos existirem em um meio externo à
aplicação que os criou (ex. bancos de dados);
• BDR surgiram na década 70 (padrão estruturado);
• BDR não suportam diversos conceitos OO (herança,
composição, agregação, polimorfismo, métodos, etc);
• BD OO ainda tem pouca adoção (desempenho inferior,
pouca documentação, ferramentas não tão maduras);
• BDR são amplamente utilizados para armazenar objetos,
mas há uma dissonância corrigida pelo uso de técnicas de
mapeamento objeto-relacional (MOR);
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
6
8. O que podemos melhorar ?
<?php
// conecta ao banco
$conn = pg_connect("dbname=livro user=postgres");
// string sql
$sql = "select id, nome from cidade order by id";
echo '<table border=1>'; // abre tabela
$result=pg_query($conn,$sql); // roda o sql
while ($row=pg_fetch_array($result))
{
• detalhes de conexão
// exibe resultados
explicitos;
echo '<tr>';
• camada visual
echo "<td>{$row['id']}</td>";
echo "<td>{$row['nome']}</td>";
misturada com acesso
echo "</tr>";
ao banco de dados;
}
• SQL espalhado pelo
// fecha tabela
código -fonte;
echo "</table>";
pg_close($conn);
?>
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
8
9. Gateways
• Em algum momento, precisaremos armazenar as
informações da aplicação em um banco de dados;
• Deve-se evitar ter código SQL juntamente com a camada de
negócios. Maior acoplamento, menor reuso;
• Um Gateway é uma interface que se comunica com um
recurso externo, escondendo seus detalhes;
• Para implementar um gateway, criamos uma classe para
manipular o acesso à uma tabela do banco de dados;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
9
10. Table Data Gateway
• Um Table Data Gateway é um objeto que possui métodos
para leitura, escrita e pesquisa de registros de uma tabela;
• Pode ser implementada por uma classe responsável por
persistir (inserir, alterar, excluir) e retornar dados do BD;
• É comum encontrarmos em um Table Data Gateway
métodos como insert(), update(), delete(), get(),
findByName(), dentre outros;
Obs: Table Data Gateway é
por natureza State Less, ou
seja, não mantém o estado
de suas propriedades, atua
simplesmente como ponte
entre o objeto de negócio e o
banco de dados.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
10
11. Table Data Gateway
• Uma (1) classe por tabela do banco de dados. Apenas uma
instância desta classe irá manipular todos os registros;
• Um Table Data Gateway é por definição stateless, uma vez
que temos apenas um objeto para gerenciar todos registros
de uma tabela;
• Por isto é necessário sempre identificar o registro sobre o
qual o método estará operando (ID ou RecordSet);
• Um Table Data Gateway pode ser utilizado como
mecanismo de persistência tanto para um Domain Model
quanto para um Table Module;
• Devido à sua natureza stateless, ele funciona de maneira
mais natural quando a camada de negócios é Table Module;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
11
12. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
12
13. Row Data Gateway
• É um objeto que representa um registro do banco de dados;
• Cada instância (objeto) representa um registro diferente;
• Cada objeto se comporta exatamente como um registro,
suas propriedades represem as colunas do banco de dados,
além de ter métodos para armazená-lo no banco de dados;
Obs: Row Data Gateway é
StateFull, ou seja, mantém os
valores de suas propriedades
ao longo do seu ciclo de vida,
não sendo necessário passar
todos valores novamente via
parâmetros, como no caso do
Table Data Gateway.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
13
14. Row Data Gateway
• No Row Data Gateway temos um objeto para manipular
cada registro de uma tabela;
• Diferente do Table Data Gateway, onde temos um objeto
para manipular todos os registros de uma tabela;
• Assim como um objeto representa um registro, cada um de
seus atributos representarão as colunas da tabela;
• Podemos tratar os objetos como statefull, uma vez que seus
atributos corresponderão aos dados armazenados na BD. Não
sendo necessário passar ID's ou RecordSets;
• Assim como Table Data Gateway, o Row Data Gateway
fornece um objeto com uma interface que permite que o
desenvolvedor acesse o banco de dados sem precisar
conhecer a linguagem SQL;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
14
15. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
15
16. Conclusão parcial
• Qual a diferença entre um gateway (Table Data Gateway ou
Row Data Gateway) para um objeto de negócio (Domain
Model ou Table Module) ?
▪ A diferença primordial é que objetos de negócio contém
regras de negócio, cálculos, tomadas de decisão, mas não
contém acesso direto à dados.
▪ O acesso à recursos externos como bancos de dados é
realizado justamente pelos gateways que só possuem
métodos de persistência, sem nenhum método de
negócio (*);
▪ * Com exceção do padrão Active Record, ainda não visto.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
16
17. Active Record
• Row Data Gateway não possui
métodos do modelo de negócios,
somente métodos de acesso à
base de dados;
• Quando adicionamos lógica de
negócio à um Row Data Gateway,
temos um Active Record;
• Com o Active Record, temos uma
única camada, onde temos lógica
de negócios (modelo conceitual)
e métodos de persisência do
objeto na base de dados
(gateway);
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
17
18. Active Record
• Um Active Record é um objeto que se comporta como um
registro do banco de dados, encapsulando o acesso à este
(persistência) e contendo ainda a lógica de negócios
relativa à estes dados;
• Um Active Record pode ser visto como um Domain Model
cujas classes possuem uma estrutura muito parecida com a
estrutura do banco de dados;
• Active Records tem seu uso mais indicado quando a
camada de negócios tiver uma
estrutura similar à
estrutura do Banco de Dados;
• Em casos em que a lógica de negócios for de complexidade
maior, utilizando combinações de relacionamentos da
orientação a objetos como herança, agregações e
composições, melhor usar Data Mapper;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
18
19. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
19
20. Identity Field
Os objetos em memória possuem sua unicidade garantida
por meio de mecanismos da linguagem (ponteiros);
Os objetos são acessados por meio de variáveis que
apontam para endereços de memória;
Os registros de bancos de dados são identificados por chaves
numéricas, conhecidas como chaves primárias;
Identity Field visa trazer também para a memória (objeto),
o campo identificador do registro no BD (primary key);
Isto possibilita carregarmos o objeto, alterarmos em
memória e posteriormente persistirmos novamente;
É importante que cada tabela na base de dados possua
apenas um campo como chave primária (ñ composto);
Não usar campos c/ significado (imutabilidade e unicidade);
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
20
21. Foreign Key Mapping - Associações
• As associações são um tipo de relacionamento onde um
objeto tem uma propriedade que referencia outro;
▪ Ex: $pessoa->cidade = new Cidade;
• Os objetos em memória estão relacionados por meio de
ponteiros de memória, mecanismo que não existe no BD;
• No banco de dados, os registros são relacionados por meio
de chaves primárias e chaves estrangeiras;
• Para mapearmos um objeto para o banco de dados,
precisamos de um campo de identificação (Identity Field),
ou seja, a chave primária também presente no objeto;
• Para mapearmos relacionamentos entre objetos, utilizamos
a mesma técnica, mas implementando o mapeamento
através do uso de chaves estrangeiras (Foreign Keys);
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
21
22. Foreign Key Mapping - Associações
Modelo de Objetos
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
22
23. Foreign Key Mapping - Associações
Modelo Relacional
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
23
24. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
24
25. Foreign Key Mapping - Composições
• No relacionamento de composição, um objeto pode conter
de uma à várias instâncias de um outro objeto, sendo
responsável pela sua criação e destruição;
▪ class Pessoa ...
▫$this->telefones[] = new Telefone;
• Uma pessoa poderá ter vários telefones que são
armazenados na forma de um atributo no objeto Pessoa,
chamado $telefones. Este atributo na verdade é um array
de objetos do tipo Telefone;
• Os objetos Telefone fazem são parte do objeto Pessoa, ou
seja, um objeto Telefone (parte) fará parte somente de um
único objeto Pessoa (todo). Quando o objeto Pessoa for
destruído, seus objetos telefone também serão;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
25
26. Foreign Key Mapping - Composições
Modelo de Objetos
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
26
27. Foreign Key Mapping - Composições
Modelo Relacional
Obs: Como a maioria dos bancos de dados relacionais não aceita campos
multi-valorados, é necessário inverter a direção do relacionamento.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
27
28. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
28
29. Association Table Mapping
• Na agregação, também temos uma relação todo/parte
como na composição, mas desta vez o objeto-parte não
está intrinsicamente ligado ao objeto-todo;
• Quando destruímos o objeto-todo, os objetos-parte ainda
continuam a existir, isto por que uma eles ttambém pode
pertencer à diferentes objetos-todo (relação N-N);
• No caso a seguir, temos uma agregação, onde um objeto
CestaCompras, representa uma cesta de compras em um
sistema de comércio eletrônico;
• A diferença para a composição é que um produto pode fazer
parte de cestas de compras diferentes e estes objetos são
criados no contexto externo à classe CestaCompras;
• Não podemos representar a relação somente com PK<->FK;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
29
30. Association Table Mapping
Modelo de Objetos
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
30
31. Association Table Mapping
Modelo Relacional
Obs: A tabela itens_cesta será totalmente manipulada pela classe
CestaCompras, ou seja, será totalmente transparente ao programador.
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
31
32. Mapeamento de Heranças
• Existem tipos de relacionamentos da orientação a objetos
para os quais não existe suporte nativo na maioria dos BD
relacionais (associação, composição, agregaçã);
• Outro relacionamento não suportado é a herança;
• Pelo mecanismo de herança, podemos construir uma
hierarquia de classes em nossa aplicação, onde estas podem
herdar estrutura (atributos) e comportamento (métodos);
• Salvo algumas exceções de BD's que implementam um
mecanismo objeto-relacional não temos presente na base
de dados o relacionamento de herança entre classes;
• Mesmo assim, não são todos bancos de dados que o fazem, e
os que implementam o fazem de maneira não padronizada,
o que dificulta uma possível migração de banco de dados;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
32
33. Mapeamento de Heranças
• Existem basicamente três formas de mapear um
relacionamento de herança. Para exemplificar, iremos
tomar por base o seguinte diagrama de classes:
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
33
34. Single Table Inheritance
• Criação de uma tabela contendo os campos de toda a
estrutura da herança, ou seja, a soma de todos atributos;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
34
35. Single Table Inheritance
• Como diferenciar quando um registro é um livro ou quando
é um DVD ? Neste caso, se torna obrigatório criarmos um
campo indicando o tipo do objeto na tabela;
• Nunca teremos todos os campos da tabela preenchidos;
• Se o material for um Livro, artista, gravadora e duração
ficarão vazios. Se o material for um DVD, autor, editora e
páginas ficarão vazios;
• Os gerenciadores modernos de banco de dados otimizam
bastante o armazenamento de informações, diferentemente
de bancos antigos como DBF ou Cobol;
• Mais simples e fácil de implementar, pois dispensa o uso de
joins entre tabelas, e com um simples SELECT, conseguimos
trazer quaisquer informações na memória,
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
35
36. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
36
37. Concrete Table Inheritance
• Uma tabela para cada classe concreta da hierarquia, ou
seja, para cada classe instanciável ou nodo-folha;
• Cada tabela deve ter além dos atributos da própria classe
que ela está mapeando, todos atributos da classe pai;
• Cada tabela contém somente os campos relativos ao seu
contexto, diferentemente do Single Table Inheritance;
• Apesar de estarmos trabalhando com tabelas diferentes,
estamos armazenando um objeto da mesma hierarquia;
• Não podemos ter dois materiais com o mesmo código, só por
que um é Livro e o outro é DVD; Os objetos devem ser
tratado com unicidade entre as duas tabelas;
• Não faz sentido uma listagem de materiais trazer materiais
diferentes com o mesmo código;
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
37
38. Concrete Table Inheritance
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
38
39. Class Table Inheritance
• Criação de uma tabela para cada classe da estrutura de
herança e relacionarmos estas tabelas através de pares de
chaves primárias e chaves estrangeiras;
• Leva à uma maior normalização do banco de dados frente
aos dois outros patterns;
• Cada classe e cada atributo do modelo de objetos
encontram exatamente um correspondente no modelo do
banco de dados;
• Para persistir os objetos torna-se necessário inserir em
várias tabelas (cfe níveis), assim como para carregar
objetos torna-se necessário realizar joins entre tabelas (cfe
níveis);
• Objetos podem trocar de tipo (transição na hierarquia),
Estagiário pode vir a ser efetivado (hierarquia de pessoas);
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
39
40. Class Table Inheritance
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
40
41. code, please...
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
41
42. Leitura Recomendada :-)
Pablo Dall'Oglio [pablo@php.net]
Enterprise Design Patterns:: com exemplos do livro PHP – Programando com Orientação a Objetos
www.adianti.com.br/phpoo
42