Desenvolvendo aplicações em camadas com PHP 5
Short Description
Download Desenvolvendo aplicações em camadas com PHP 5...
Description
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 private private private private
$id; $nome; $idade; $sexo; $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 private $usuario private $senha private $banco
= = = =
"localhost"; "root"; ""; "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."]"; echo "DESCRIÇÃO : ".$teste["erro"].""; echo "COMANDO : ".$this->SQL.""; }else{ switch ($this->code) { case 2003: echo "CÓDIGO : [".$this->code."]"; echo "DESCRIÇÃO : Não foi possível conectar ao servidor MYSQL"; die; break; case 2005: echo "CÓDIGO : [".$this->code."]"; echo "DESCRIÇÃO : Nome do servidor é desconhecido"; 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
View more...
Comments