• Nenhum resultado encontrado

Desenvolvendo aplicações em camadas com PHP 5

N/A
N/A
Protected

Academic year: 2021

Share "Desenvolvendo aplicações em camadas com PHP 5"

Copied!
18
0
0

Texto

(1)

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:

(2)

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.

(3)

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.

(4)

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:

(5)

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.

(6)

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.

(7)

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.

(8)

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.

(9)

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.

(10)
(11)

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; }

(12)

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(); } } }

(13)

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); }

(14)

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)); }

(15)

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); }

(16)

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); }

(17)

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

(18)

Created with an unregistered version of SCP PDF Builder

Referências

Documentos relacionados

Effects of Continuance, Affective, and Moral Commitment on the Withdrawal Process: An Evaluation of Eight Structural Equation Models.. The Academy of

Foi apresentada, pelo Ademar, a documentação encaminhada pelo APL ao INMETRO, o qual argumentar sobre a PORTARIA Nº 398, DE 31 DE JULHO DE 2012 E SEU REGULAMENTO TÉCNICO

Neste trabalho avaliamos as respostas de duas espécies de aranhas errantes do gênero Ctenus às pistas químicas de presas e predadores e ao tipo de solo (arenoso ou

Verificar a efetividade da técnica do clareamento dentário caseiro com peróxido de carbamida a 10% através da avaliação da alteração da cor determinada pela comparação com

O projeto Capacitar para mudar - Ações educativas em um hospital de urgência e emergência, visa reduzir a quantidade de resíduo gerado na unidade, com foco especifico nos

Esta fala de Waiwai explicita dois tipos de experiências relativas a filmagens que os Waiãpi conheceram: uma negativa, que remete a uma primeira experiência nos anos 70 com os

Varr edura TCP Window ( cont inuação) ACK- win manipulado Não Responde ACK- win manipulado ICMP Tipo 3 Firewall Negando Firewall Rejeitando Scanner de Porta... Var r edur a FI N/

RESUMO - O trabalho objetivou avaliar a qualidade das sementes de arroz utilizadas pelos agricultores em cinco municípios (Matupá, Novo Mundo, Nova Guarita, Alta Floresta e Terra