Sei sulla pagina 1di 18

Autor: Ricardo Francisco Minzé Júnior

Desenvolvendo aplicações em camadas com PHP 5.


Talvez a primeira vista você ache estranha a palavra “Camada” em programação, mas o que
vem a ser Camada?
Segundo o dicionário:
Camada
1 - Qualquer matéria de alguma espessura estendida sobre uma superfície.
2 - Substância aplicada sobre outra.
3 - Classe, categoria.
4 - Grande quantidade

Realidade na Programação:
Camada
Trazendo para nossa realidade de Programação, usar este conceito seria uma forma de
organizar o trabalho separando o sistema em partes menores (camadas), para resolver
problemas separadamente (separação de conceitos) desta forma o estruturando em
camadas.(uma sobre a outra)
Vantagens do uso de camadas:

Modularidade:
Melhor estruturação do sistema
Melhor entendimento
Coesão (Harmonia na relação dos arquivos)
Facilidades de Manutenção:
Custos de manutenção representam em média 75% do custo total do software,
então se um sistema está com todas suas tarefas e funcionalidades bem
divididas por suas partes menores, este será de facílima manutenção.

Estrutura básica das Camadas:


Autor: Ricardo Francisco Minzé Júnior

A estrutura a seguir será usada para o exemplo que estará disponível para download, ele é equivalente a o
esquema acima, mas mostrando a estrutura de diretórios para que o leitor possa se guiar no exemplo.

Classes Básicas:
Composta por classes simples do sistema, apenas com métodos de acesso aos seus
atributos.
Coleção de Dados:

Esta camada é responsável por manipular diversos objetos das classes básicas.
Normalmente possui alguma estrutura de armazenamento de objetos das classes
(Ex: Array de Objetos).
Conhecida também com Camada de Persistência.

Coleção de Negócios:

Esta camada é responsável por realizar críticas de Negócio específicas a uma determinada classe
básica da aplicação utilizando-se de uma Coleção de Dados, para lhe dar suporte a persistência
de objetos da aplicação.

Ex: “O usuário não pode ter a idade maior que a idade máxima de adesão ao plano” (Regra de
plano de saúde), ou “Não é possível inserir duas contas com o mesmo número” (Regra do
Banco).

Disponibiliza serviços específicos do Negócio envolvido


Ex: Funções específicas para aquela classe básica usada pela classe de Negócio.
Geralmente é chamada de cadastro.
Autor: Ricardo Francisco Minzé Júnior
Classes Básicas
Classes mais simples do sistema.
Vamos começar pela classe que trata do comportamento de um tipo de ator, alguém que interage com o
sistema, nesse exemplo vamos criar a classe Pessoa.
Autor: Ricardo Francisco Minzé Júnior
Interface

Vamos agora definir quais são as funcionalidades básicas de Persistência de uma Pessoa, como ela deve
ser guardada.
Essa forma de armazenamento é chamada de Repositório.
Vamos abstrair um pouco...
Pense que uma Pessoa pode ser persistido de diversas formas, mas para isso preciso saber quais
funcionalidades são necessárias para a persistência.

Observe que esta classe apenas possui assinaturas de métodos.

Você deve estar se perguntando porque uma classe só com assinatura de métodos?
Antes de responder esta pergunta vou citar um conceito usado no PHP5, que será de extrema importância
para se trabalhar com camadas, ele é chamado de Indução de Tipos.
Com este recurso você pode forçar seu método a receber um determinado tipo de dado.
Ex:
public function inserir(Pessoa $objPessoa)
{
$this->inserir($objPessoa);
}

* Vou passar um objeto do Tipo Bicho para esta função.


inserir($objBicho)

* Causará o seguinte erro:

Fatal error: Argument 1 must be an instance of Pessoa


Autor: Ricardo Francisco Minzé Júnior

O Php informa que o objeto que deve ser passado como parâmetro da função deve ser uma instância da
classe Pessoa.
Agora que você sabe do conceito de Indução de Tipos, podemos responder aquela pergunta.

Porque uma classe só com assinatura de métodos?


Quando nós criamos uma Interface, ela será implementada por outra classe que obrigatoriamente terá
que implementar todos os métodos que estão assinados na Interface.

Automaticamente esta classe que implementa a interface será do tipo da interface, e a partir daí o
conceito de interface passa ter sentido.

Imagine que seu sistema pode sofrer mudanças e uma delas será onde salvar os dados, neste caso podem
ser salvos em um arquivo txt ou num banco de dados, por exemplo.

Para deixar flexível e não amarrar o sistema, podemos usar uma Interface que é implementada por varias
classes, mas que apenas uma será usada.

Vamos dar um exemplo:

Criei a interface Pessoa que assina o Método Inserir:

Agora vamos criar uma classe que implementa a Interface RepositorioPessoa, digamos que eu resolvi
salvar os registros em um banco de dados.
Autor: Ricardo Francisco Minzé Júnior
Mas de repente precisei salvar meus registros agora em um arquivo TXT, então vou criar uma classe
para salvar registros em um TXT, e ela terá que implementar a interface, e obrigatoriamente precisa
implementar seus métodos.

Então podemos criar uma classe que usa nossa interface RepositorioPessoa da seguinte maneira:
Autor: Ricardo Francisco Minzé Júnior
Como RepositorioPessoaBanco e RepositorioPessoaArquivo são do Tipo
RepositorioPessoa(Interface), se eu passar qualquer uma das duas minha Classe CadastroPessoa vai
entender que foi passado para ela uma Interface RepositorioPessoa, dessa maneira não gerando erros, e
deixando flexibilidade na hora de salvar meus registros.

Se eu quiser salvar em Arquivo só é chegar na minha Fachada e trocar:


$this->RepositorioPessoa = new RepositorioPessoaBanco();
PARA
$this->RepositorioPessoa = new RepositorioPessoaArquivo();

E agora Minha classe CadastroPessoa trabalha normalmente.

$this->CadastroPessoa = new CadastroPessoa($this->RepositorioPessoa)

Fachada

A idéia da Fachada é fornecer uma instância única para o sistema, de forma que o usuário só terá acesso
aos seus “comportamentos superficiais”, o próprio nome já diz, “FACHADA”, então o que devemos
fazer para definir uma fachada ?
Primeiramente vamos usar um padrão de projetos “Design Pattern”, esses padrões são de formas de
implementações para definir um comportamento padrão, facilitando assim a nossa vida como
desenvolvedores, aumentando a manutenibilidade dos sistemas.
Então a idéia é a seguinte: definir um atributo do tipo da classe como static private, deixar o construtor
como private para garantir que não será possível acessar o mesmo, criar um método static que retorna
uma Fachada, e perguntar se já foi instanciada.
Autor: Ricardo Francisco Minzé Júnior
Exceções

Não podemos nos esquecer das exceções, onde é possível tratar erros e dar um curso
alternativo ao programa.

Poderíamos ter criado Exceções para a classe Pessoa, mas para melhor ser visualizado
na prática resolvi criar uma única classe de exceção dedicada exclusivamente para
erros de banco, como falha na conexão ou até mesmo erros nas strings de SQL.

Nesta classe quando é levantada uma exceção ela recebe o código do erro e faz uma
busca no banco de dados onde os erros estão em português, se o erro não estiver
cadastrado ela exibe o erro do em Inglês do MYSQL.
Autor: Ricardo Francisco Minzé Júnior

Caso a conexão não seja efetuada ou o servidor é desconhecido esta classe de exceção
trata o erro dizendo que não é possível conectar ou o servidor é desconhecido.

A seguir os trechos de código mostram o momento onde a exceção é detectada e passada


para classe ExcecaoBanco fazer o tratamento.
1º Situação: Tentativa de Conexão

2º Situação: Execução de um comando SQL

Apresentação
Esta é a última camada que devemos nos importar, será a forma que o usuário
visualizará seu sistema, e quando seu sistema está dividido desta forma você poderá
mudar o layout do seu sistema ou site sem muito esforço para a manutenção.
A seguir será mostrado um diagrama de classes relacionando essas camadas e
envolvendo exemplos de código citados nos exemplos anteriores.
Autor: Ricardo Francisco Minzé Júnior
Autor: Ricardo Francisco Minzé Júnior

Agora todas as classes para você analisar e testar em seus exemplos:


Pessoa.php

class Pessoa
{
private $id;
private $nome;
private $idade;
private $sexo;
private $cpf;

public function Pessoa($id, $nome, $idade, $sexo, $cpf)


{
$this->id = $id;
$this->nome = $nome;
$this->idade = $idade;
$this->sexo = $sexo;
$this->cpf = $cpf;
}

public function setId($id)


{
$this->id = $id;
}

public function getId()


{
return $this->id;
}
public function setNome($nome)
{
$this->nome = $nome;
}
public function getNome()
{
return $this->nome;
}
public function setIdade($idade)
{
$this->idade = $idade;
}
public function getIdade()
{
return $this->idade;
}
public function setSexo($sexo)
{
$this->sexo = $sexo;
}
public function getSexo()
{
return $this->sexo;
}
public function setCpf($cpf)
{
$this->cpf = $cpf;
}
public function getCpf()
{
return $this->cpf;
}
}
Autor: Ricardo Francisco Minzé Júnior
Conexao.php

error_reporting("NONE");

require_once("../../excecoes/banco/ExcecaoBanco.php");

class Conexao
{
private $servidor = "localhost";
private $usuario = "root";
private $senha = "";
private $banco = "pessoa";

public function Conexao()


{
}
public function conectar()
{
try{
$link =
mysql_connect($this->servidor,$this->usuario,$this->senha);
if(mysql_errno() > 0)
{
throw new ExcecaoBanco(mysql_error(),mysql_errno());
}
mysql_select_db($this->banco,$link);
return $link;

}catch(ExcecaoBanco $e){

$e->BuscarErro();
}
}
public function desconectar()
{
mysql_close();
}

public function execute($SQL)


{
$ResultSet = mysql_query($SQL);
print $SQL;
try
{
switch (gettype($ResultSet))
{
case "boolean":

if(!$ResultSet)
{
throw new
ExcecaoBanco(mysql_error(),mysql_errno(),$SQL);
}
break;

case "resource":
return mysql_fetch_array($ResultSet);
break;
}

}catch(ExcecaoBanco $e){

$e->BuscarErro();
}
}
}
Autor: Ricardo Francisco Minzé Júnior
ExcecaoBanco.php

class ExcecaoBanco extends Exception


{
private $SQL;

public function ExcecaoBanco($mensagem, $codigo, $SQL="")


{
parent::__construct($mensagem, $codigo);
$this->SQL = $SQL;
}

public function BuscarErro()


{
if( ($this->code != 2003) && ($this->code != 2005))
{
$SQL = "SELECT * FROM ERRO WHERE ID=".$this->code;
$ResultSet = mysql_query($SQL);
$teste = mysql_fetch_array($ResultSet);
echo "CÓDIGO : [".$this->code."]<br>";
echo "DESCRIÇÃO : <font
color='red'>".$teste["erro"]."</font><br>";
echo "COMANDO : <b>".$this->SQL."</b>";
}else{
switch ($this->code)
{

case 2003:

echo "CÓDIGO : [".$this->code."]<br>";


echo "DESCRIÇÃO : <font color='red'>Não foi
possível conectar ao servidor MYSQL</font><br>";
die;
break;

case 2005:

echo "CÓDIGO : [".$this->code."]<br>";


echo "DESCRIÇÃO : <font color='red'>Nome do
servidor é desconhecido</font><br>";
die;
break;
}
}

}
}

RepositorioPessoa.php

interface RepositorioPessoa
{
public function inserir(Pessoa $objPessoa);
public function atualizar(Pessoa $objPessoa);
public function deletar($id);
public function pesquisar($id);
}
Autor: Ricardo Francisco Minzé Júnior
RepositorioPessoaBanco.php

require_once("../../repositorio/banco/Conexao.php");
require_once("../../repositorio/pessoa/RepositorioPessoa.php");
require_once("../../repositorio/repositoriosql/pessoa/RepositorioPessoaSQL.php");

class RepositorioPessoaBanco implements RepositorioPessoa


{
private $Conexao;
private $RepositorioPessoaSQL;

public function RepositorioPessoaBanco()


{
$this->Conexao = new Conexao();
$this->Conexao->conectar();
$this->RepositorioPessoaSQL = new RepositorioPessoaSQL();
}

public function inserir(Pessoa $objPessoa)


{

$this->Conexao->execute($this->RepositorioPessoaSQL->inserir($objPessoa));
}

public function atualizar(Pessoa $objPessoa)


{

$this->Conexao->execute($this->RepositorioPessoaSQL->atualizar($objPessoa));
}

public function deletar($id)


{

$this->Conexao->execute($this->RepositorioPessoaSQL->deletar($id));
}

public function pesquisar($id)


{
return
$this->Conexao->execute($this->RepositorioPessoaSQL->pesquisar($id));
}
}
Autor: Ricardo Francisco Minzé Júnior
RepositorioPessoaSQL.php
class RepositorioPessoaSQL
{
public function RepositorioPessoaSQL()
{
}

public function inserir(Pessoa $objPessoa)


{
$SQL = "INSERT INTO
PESSOA(ID,NOME,IDADE,SEXO,CPF)VALUES(".$objPessoa->getId().",'".$objPessoa->getNome(
)."',".$objPessoa->getIdade().",'".$objPessoa->getSexo()."','".$objPessoa->getCpf().
"')";
return $SQL;
}
public function atualizar(Pessoa $objPessoa)
{
$SQL = "UPDATE PESSOA SET
ID=".$objPessoa->getId().",NOME='".$objPessoa->getNome()."',IDADE=".$objPessoa->getI
dade().",SEXO='".$objPessoa->getSexo()."',CPF='".$objPessoa->getCpf()."' WHERE
ID=".$objPessoa->getId();
return $SQL;
}
public function deletar($id)
{
$SQL = "DELETE FROM PESSOA WHERE ID = ".$id;
return $SQL;
}
public function pesquisar($id)
{
$SQL = "SELECT * FROM PESSOA WHERE ID = ".$id;
return $SQL;
}
}

CadastroPessoa.php
require_once("../../repositorio/pessoa/RepositorioPessoa.php");

class CadastroPessoa
{
private $RepositorioPessoa;

public function CadastroPessoa(RepositorioPessoa $RepositorioPessoa)


{
$this->RepositorioPessoa = $RepositorioPessoa;
}

public function inserir(Pessoa $objPessoa)


{
$this->RepositorioPessoa->inserir($objPessoa);
}

public function atualizar(Pessoa $objPessoa)


{
$this->RepositorioPessoa->atualizar($objPessoa);
}

public function deletar($id)


{
$this->RepositorioPessoa->deletar($id);
}
public function pesquisar($id)
{
return $this->RepositorioPessoa->pesquisar($id);
}
}
Autor: Ricardo Francisco Minzé Júnior
FachadaPessoa.php

require_once("../../basica/pessoa/Pessoa.php");
require_once("../../negocio/pessoa/CadastroPessoa.php");
require_once("../../repositorio/pessoa/RepositorioPessoaBanco.php");

class FachadaPessoa {

private $RepositorioPessoa;
private $CadastroPessoa;
private static $instancia = null;

private function InitCadastros()


{
$this->RepositorioPessoa = new RepositorioPessoaBanco();
$this->CadastroPessoa = new
CadastroPessoa($this->RepositorioPessoa);
}

private function FachadaPessoa()


{
$this->InitCadastros();
}

public function getInstancia()


{
if (self::$instancia == null)
{
self::$instancia = new FachadaPessoa();
}

return self::$instancia;
}

public function inserir(Pessoa $objPessoa)


{
$this->CadastroPessoa->inserir($objPessoa);
}

public function atualizar(Pessoa $objPessoa)


{
$this->CadastroPessoa->atualizar($objPessoa);
}

public function deletar($id)


{
$this->CadastroPessoa->deletar($id);
}

public function pesquisar($id)


{
return $this->CadastroPessoa->pesquisar($id);
}
}
Autor: Ricardo Francisco Minzé Júnior
Apresentação.php

require_once("../../basica/pessoa/Pessoa.php");
require_once("../../fachada/pessoa/FachadaPessoa.php");

$fachada = FachadaPessoa::getInstancia();
$objPessoa = new Pessoa(1,"Ricardo Minzé",23,'M',123);

$fachada->inserir($objPessoa);
// $fachada->atualizar($objPessoa);
// $fachada->deletar(1);
// $objPessoa = $fachada->pesquisar(1);

Espero ter contribuído para o conhecimento comum entre os que fazem a comunidade PHP.

Ricardo Francisco Minzé Júnior


Desenvolvedor WEB
Autor: Ricardo Francisco Minzé Júnior

Created with an unregistered version of SCP PDF Builder

You can order SCP PDF Builder for only $19.95USD from http://www.scp-solutions.com/order.html

Potrebbero piacerti anche