Construindo uma Arquitetura de Desenvolvimento em PHP 5

16

Click here to load reader

Transcript of Construindo uma Arquitetura de Desenvolvimento em PHP 5

Page 1: Construindo uma Arquitetura de Desenvolvimento em PHP 5

Construindo uma Arquitetura de Desenvolvimento em PHP 5Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Iremos, nesse artigo, entender como funciona um Sistema divido em Camadas e construir uma classe de manipulação de Banco de Dados.

Pré-Requisitos

Saber conceitos de Orientação a Objeto, e XML.

Introdução

O PHP vem crescendo muito e está sendo usado hoje em dia em desenvolvimento de software e vou falar e mostrar exemplos práticos ao longo do tempo sobre esse tipo de aplicação com o php. Geralmente, quando construímos aplicações pequenas ou de fácil interação, nós, “falando de programação”, colocamos a “lógica do negócio” nas mesmas páginas e não nos preocupamos muito com a divisão da lógica de programação em partes.

Mas para aplicações de médio e grande porte (E-Commerce, Portais, etc) se fizermos isso, iremos com certeza cair em uma bagunça que não teremos mais volta, já vi muito dessas coisas aconterem com pessoas conhecidas, é por isso que eu vou conceituar e construir uma “Arquitetura de Desenvolvimento” para nosso sistema ganhar mais performance e abrangência. Também conhecida como arquitetura das três camadas (Banco de Dados, Regras de Negócio e Interface com o Usuário).

Vamos entender mais com a figura abaixo:

Entendendo

Interface com o Usuário - Entrada e saída de dados. A única visão do sistema pelo usuário. Regras de Negócio - São Classes que validam do dados vindo da Interface com Usuário, retornam mensagens de erro quando houverem. Também responsável por levar e trazer informações do Banco de Dados.Banco de Dados - Camada responsável pela comunicação e manutenção de dados e informações.

Agora, como construir esse tipo de aplicação? Bom, iremos precisar de uma Pattern, o que seria isso? Uma organização das camadas. Veja a figura abaixo e compreenda.

Page 2: Construindo uma Arquitetura de Desenvolvimento em PHP 5

A pasta mãe eu chamo de fábrica porque nós estamos propondo uma fábrica de software (pelos menos a pattern), neste artigo não irei falar sobre levantamento e requisitos.

A pasta Arquitetura irá conter as classes utilitárias do sistema, ex: Banco de Dados, E-mail, Manipulação de Arquivos, etc.

A pasta Negócio conterá as classes que compôem a lógica dos nossos sistemas. Já a pasta Sistema conterá as páginas que farão a troca de dados com o usuário.

Agora, sabendo disso, iremos construir uma pequena aplicação com esse conceitos.

A Arquitetura

Na pasta Arquitetura ficam as classes utilitárias dos aplicativos a serem criados, veremos agora a classe que manipula o banco de dados (usarei o MySQL, mas nada impede de usar outro banco).

class BancodeDados {

private $host;private $username;private $password;private $connection;private $squema;

public function BancodeDados($resource) {

$xml = simplexml_load_file($resource);

$this->host = $xml->sessionfactory->host;$this->username = $xml->sessionfactory->username;$this->password = $xml->sessionfactory->password;$this->squema = $xml->sessionfactory->database;

}

public function conecta() {

$this->connection = mysql_connect($this->host, $this->username,$this->password);mysql_select_db($this->squema,$this->connection);

return $this->connection;

}

public function desconecta() {

mysql_close($this->connection);

}

public function updateSQL($sql) {

Page 3: Construindo uma Arquitetura de Desenvolvimento em PHP 5

$r = mysql_query($sql,$this->connection);if($r == 0) {return false;} else {return true;}

}

public function executaSQL($sql) {

$retorno = mysql_query($sql,$this->connection);return $retorno;

}

public function iniciarTransacao() {

$this->executaSQL("begin");

}

public function efetivarTransacao() {

$this->executaSQL("commit");

}

public function desfazerTransacao() {

$this->executaSQL("rollback");

}

}

Entendendo o código

A classe receberá os atributos host, username, password e squema para fazer a conexão.Estes atributos vindos de um arquivo xml. Sendo que o caminho desse arquivo é passado como parâmetro no método construtor.

--version 1.0----configuration----sessionfactory----host--localhost--/host----username--root--/username----password--abc--/password----database--exclusiva--/database----/sessionfactory----/configuration--

No método construtor os atributos são inicializados com os dados vindos do XML. O método updateSQL() executa a query e retorna true ou false. O método executaSQL() executa a query e retorna os registros. Os métodos iniciarTransacao(), efetivarTransacao() e desfazerTransacao() são para transação de banco de dados.

Com isso, nós já temos uma parte das camadas prontas, uma parte da camada Banco de Dados com a classe manipuladora. Separamos o código que geralmente é posto onde você recebe os dados e já

Page 4: Construindo uma Arquitetura de Desenvolvimento em PHP 5

conecta e executa tudo. Agora, nós temos um objeto que irá fazer isso, acontecendo também o re-uso de código porque toda aplicação que necessitar interagir com o banco de dados irá usar o objeto BancodeDados.

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 02Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Olá pessoal. Já vimos no artigo passado a camada "arquitetura", onde criamos uma classe de manipulação de banco de dados (na arquitetura ficam as classes utilitárias comuns a todos os sitemas ex: BancoDeDados, Manipulação de Arquivos, E-mail, etc), que será usada pela nossa aplicação e para várias outras que vocês queiram fazer.

Estudo de Caso

Vamos pegar um caso MUITO simples para o entendimento de todos. Tenho um site e quero ter o cadastro de meus clientes para no futuro eu poder fazer propagandas, estatísticas, etc. Agora que já temos o nosso objetivo, vamos começar a pensar em objetos.

O mapeamento será o seguinte:

Quem tem atributos e realiza ações? Neste nosso caso é somente o Cliente. Então só teremos o objeto Cliente.

Uma classe é formada ou de atributos e/ou de ações,estados(métodos).

E quando estamos falando das funções do sistema estamos falando do NEGÓCIO do sistema. Estamos saindo da camada da Arquitetura e entrando na cadama Negocial.

Procedimento: Na pasta negocio crie uma pasta com o nome do sistema, no nosso caso é a pasta "siscliente" (sistema de cliente) e dentro dela a pasta "cliente" e dentro dessa pasta vamos criar a entidade (classe) Cliente.

Os atributos do cliente são: código, nome, telefone, email e endereco;

Cliente.class.php

class Cliente {

    private $codigo;    private $nome;    private $telefone;    private $email;    private $endereco;

    public function setCodigo($codigo) {         $this->codigo = $codigo;     }

    public function getCodigo() {         return $this->codigo;     }

    public function setNome($nome) {         $this->nome = $nome;     }

Page 5: Construindo uma Arquitetura de Desenvolvimento em PHP 5

    public function getNome() {         return $this->nome;     }

    public function setTelefone($telefone) {         $this->telefone = $telefone;     }

    public function getTelefone() {         return $this->telefone;     }

    public function setEmail($email) {         $this->email = $email;     }

    public function getEmail() {         return $this->email;     }

    public function setEndereco($endereco) {         $this->endereco = $endereco;     }

    public function getEndereco() {         return $this->endereco;     }

}

A diferença entre a Entidade e o Objeto DAO. A entidade somente conterá os atributos e os métodos de acesso a esses métodos.

O DAO conterá os métodos que realizam as ações (incluir,alterar,etc) da Entidade relacionada. Ou seja, para cada Objeto.class.php e esse objeto realiza operações existirá um ObjetoDAO.class.php.

O Data Access Object (DAO) significa "Objeto de acesso ao Banco", ou seja todas as operações que necessitarem manter alguma informação com o banco de dados será essa classe que fará a manipulação.

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 03Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Olá pessoas. Conversaremos hoje sobre o o Data Access Object (DAO). Como estou falando da parte negocial do sistema, veremos uma classe que terá o acesso ao banco de dados para realizar as operações de busca, inserção, etc.

Como a nossa proposta é separar em camadas a nossa aplicação, construiremos um "módulo" que fará a persistência com o banco de dados. Teremos uma classe que fará o transporte do banco e outra mais específica que executará as funções.

Cada "Entidade" (classe) que necessita fazer transações com o banco de dados terá uma classe DAO associada a ele. No caso, irei fazer a classe para a nossa entidade Cliente, que vimos no artigo passado.

A classe conterá somente métodos que realizarão funções com o objeto. Construiremos 5 métodos: incluir, recuperarTodos, recuperarPorId, alterar e excluir.

Page 6: Construindo uma Arquitetura de Desenvolvimento em PHP 5

Procedimento: Na pasta "cliente" criaremos o arquivo ClienteDAO.class.php

ClienteDAO.class.php

require_once("../../../arquitetura/DAO.class.php");

class ClienteDAO extends DAO {

public function inserir(Cliente $cliente) { $sql = "insert into cliente(nome,telefone,email,endereco)VALUES ('".$cliente->getNome()."','".$cliente->getTelefone()."','".$cliente->getEmail()."','".$cliente->getEndereco()."')";

$banco = $this->getBancoDados();

if(!$banco->updateSQL($sql)) { throw new Exception("ERRO NA QUERY CLIENTEDAO MÉTODO INSERIR CLIENTE"); } }

public function recuperarPorId($id) { $sql = "select * from cliente where id = '".$id."'";

$banco = $this->getBancoDados();

$cliente = NULL;

$retorno = $banco->executaSQL($sql); if($retorno != NULL) { while($linha = mysql_fetch_array($retorno)) { $cliente = new Cliente(); $cliente->setCodigo($linha["id"]); $cliente->setNome($linha["nome"]); $cliente->setEmail($linha["email"]); $cliente->setEndereco($linha["endereco"]); $cliente->setTelefone($linha["telefone"]); }return $cliente; } else { throw new Exception("ERRO NA QUERY CLIENTEDAO MÉTODO RECUPERAR CLIENTE POR ID"); } }

public function recuperarTodos() { $sql = "select id from cliente order by id desc";

$banco = $this->getBancoDados();

$retorno = $banco->executaSQL($sql); if($retorno != NULL) { $clientes = NULL;$i = "0";while($linha = mysql_fetch_array($retorno)) { $clientes[$i] = $this->recuperarPorId($linha["id"]);

Page 7: Construindo uma Arquitetura de Desenvolvimento em PHP 5

$i++; } return $clientes; } else { throw new Exception("ERRO NA QUERY CLIENTEDAO MÉTODO RECUPERAR CLIENTE TODOS"); } }

/* Para os métodos de alterar e excluir, segue o mesmo procedimento, podendo também ser feitos métodos para realizar funções, ex.: Recuperarpordata, etc. */

} Na pasta arquitetura crie um arquivo chamado DAO.class.php, ele será o nosso Data Access Object. DAO.class.php class DAO {

public $banco;

public function setBancoDados(BancodeDados $banco) {

$this->banco = $banco;

}

public function getBancoDados() {

return $this->banco;

}

}

O método inserirCliente recebe como parâmetro o objeto cliente e constrói a query com os dados do cliente. A classe estende a classe DAO (requerida da pasta arquitetura) que tem os métodos setBancoDados e getBancoDados.

Estes dois métodos são chamados quando instanciamos o ClienteDAO e passo o objeto BancodeDados já conectado (passado por referência). A classe usa esse objeto banco para realizar as operações.

Espero ter ajudado a entender o objeto DAO. No próximo artigo, veremos como funciona a SESSION FACADE (lê-se façeide), que é onde estão as regras de negócio do nosso sistema.

Script do Banco de Dados:

USE TEST;CREATE TABLE cliente ( id INT NOT NULL AUTO_INCREMENT, nome VARCHAR(255) NOT NULL, telefone VARCHAR(255) NOT NULL, endereco VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, PRIMARY KEY(id) );

Abraço!

Page 8: Construindo uma Arquitetura de Desenvolvimento em PHP 5

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 04Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Olá amigos. Nesta oportunidade falarei da SESSION FACADE.

A Session Facade tem um conjunto de métodos de negócio, responsável por acessar e atualizar dados. É um ponto de entrada único dos dados e funcionalidades. É uma camada de controle da lógica de negócio da aplicação. Construiremos os métodos inserirCliente e recuperarClientes.

IMPORTANTE: No caso só uma session façade para o sistema, no caso de muitas classe, esse session irá controlar toda a lógica delas, ou seja, toda a lógica de negócio do sistema será controlada pela façade.

Procedimento: Na pasta "siscliente" em negócio iremos criar o arquivo.

SessionFacade.class.php SessionFacade.class.php require_once("cliente/Cliente.class.php");require_once("cliente/ClienteDAO.class.php");

class SessionFacade {

public $banco;

public function SessionFacade(BancodeDados $banco) { $this->banco = $banco; }

public function inserirCliente(Cliente $cliente) {

if($cliente->getNome() == NULL) { throw new Exception("O NOME É UM CAMPO OBRIGATÓRIO"); }

if($cliente->getTelefone() == NULL) { throw new Exception("O TELEFONE É UM CAMPO OBRIGATÓRIO"); }

if($cliente->getEndereco() == NULL) { throw new Exception("O ENDEREÇO É UM CAMPO OBRIGATÓRIO"); }

$clienteDAO = new ClienteDAO(); $clienteDAO->setBancoDados($this->banco);

$clienteDAO->inserir($cliente);

}

public function recuperarClientes() { $clienteDAO = new ClienteDAO(); $clienteDAO->setBancoDados($this->banco);

return $clienteDAO->recuperarTodos(); }

Page 9: Construindo uma Arquitetura de Desenvolvimento em PHP 5

/* PARA OS MÉTODOS DE ALTERAR E EXCLUIR SEGUE O MESMO PROCEDIMENTO, PODENDO TAMBÉM SER FEITOS MÉTODOS PARA REALIZAR FUNÇÕES, EX: RECUPERARPORDATA, ETC. */

}

O método construtor recebe como parâmetro o banco de dados passado por referência, e o atribui a variável banco que será usada pelos métodos.

A validação dos dados eu faço com excessões que serão disparadas quando o dado não estiver de acordo com a regra.

Instancio o ClienteDAO, passo o banco por referência já conectado para o objeto usá-lo. Caso haja algum erro no ClienteDAO, lá é disparada uma excessão. É preciso dar um require_once das classes que serão usadas sempre.

Assim funciona a SessionFacade. Se houver mais classes, elas também são controladas nesta session. No próximo artigo veremos como funciona a chamada da façade e a passagem de parâmetros.

Abraço!

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 05Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Continuando a série, chegamos a uma parte que eu considero um comunicador entre a interface e a lógica do sistema - a Manter.

Chamo de Manter pois ele mantém todo o objeto, no caso, o Cliente.

Os modos de acessar a Manter serão formulários e links passando dados para a operações serem realizadas.

Procedimento: Na pasta "Sistema em Fábrica" iremos criar a pasta "siscliente", semelhante a negócio, e dentro dela o arquivo manterCliente.php.

manterCliente.class.php

require_once("../../../arquitetura/BancodeDados.class.php");require_once("../../../negocio/siscliente/SessionFacade.class.php");require_once("../../../negocio/siscliente/cliente/Cliente.class.php");

@session_start();

if(!isset($_SESSION["clientes"])) {      $_SESSION["clientes"] = NULL; }

if(isset($_POST["acao"])) {      if($_POST["acao"] == "Cadastrar") {         cadastrar();      } }

Page 10: Construindo uma Arquitetura de Desenvolvimento em PHP 5

if(isset($_GET["acao"])) {      if($_GET["acao"] == "Mostrar") {         mostrarClientes();      } }

function cadastrar() {      $banco = new BancodeDados("../../../sistema/siscliente/conexao.xml");      $sessionFacade = new SessionFacade($banco);

     try {         $banco->conecta();

        $cliente = new Cliente();         $cliente->setNome($_POST["nome"]);         $cliente->setTelefone($_POST["telefone"]);         $cliente->setEndereco($_POST["endereco"]);         $cliente->setEmail($_POST["email"]);

        $sessionFacade->inserirCliente($cliente);

        $banco->desconecta();         header("location: cadastrarCliente.php?msg=OPERAÇÃO REALIZADA COM SUCESSO");      } catch(Exception $e) {         $banco->desconecta();         header("location: cadastrarCliente.php?msg=".$e->getMessage());      }

}

function mostrarClientes() {      $banco = new BancodeDados("../../../sistema/siscliente/conexao.xml");      $sessionFacade = new SessionFacade($banco);

     try {         $banco->conecta();

        $_SESSION["clientes"] = $sessionFacade->recuperarClientes();

        $banco->desconecta();         header("location: mostrarClientes.php");

     } catch(Exception $e) {         $banco->desconecta();         header("location: mostrarClientes.php?msg=".$e->getMessage());      }

}           /* PARA OS MÉTODOS DE ALTERAR E EXCLUIR SEGUE O MESMO PROCEDIMENTO. */

No início, eu coloco as classes que eu irei utilizar e inicio a sessão com session_start. A primeira condição que eu analiso é se as sessões que eu irei utilizar já existem, caso não, eu as crio sendo nulas.

A segunda é verificar se existe algum request vindo de formulário que eu nomeio como "ação" (no caso, eu julgo ações ).

Para cada tipo de ação irá existir uma função para tratar da execução.

Como funciona a classe BancodeDados está explicada na segunda parte desta série de artigos. No próximo artigo veremos as entradas e saídas de dados.

Page 11: Construindo uma Arquitetura de Desenvolvimento em PHP 5

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 05Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Continuando a série, chegamos a uma parte que eu considero um comunicador entre a interface e a lógica do sistema - a Manter.

Chamo de Manter pois ele mantém todo o objeto, no caso, o Cliente.

Os modos de acessar a Manter serão formulários e links passando dados para a operações serem realizadas.

Procedimento: Na pasta "Sistema em Fábrica" iremos criar a pasta "siscliente", semelhante a negócio, e dentro dela o arquivo manterCliente.php.

manterCliente.class.php

require_once("../../../arquitetura/BancodeDados.class.php");require_once("../../../negocio/siscliente/SessionFacade.class.php");require_once("../../../negocio/siscliente/cliente/Cliente.class.php");

@session_start();

if(!isset($_SESSION["clientes"])) {      $_SESSION["clientes"] = NULL; }

if(isset($_POST["acao"])) {      if($_POST["acao"] == "Cadastrar") {         cadastrar();      } }

if(isset($_GET["acao"])) {      if($_GET["acao"] == "Mostrar") {         mostrarClientes();      } }

function cadastrar() {      $banco = new BancodeDados("../../../sistema/siscliente/conexao.xml");      $sessionFacade = new SessionFacade($banco);

     try {         $banco->conecta();

        $cliente = new Cliente();         $cliente->setNome($_POST["nome"]);         $cliente->setTelefone($_POST["telefone"]);         $cliente->setEndereco($_POST["endereco"]);         $cliente->setEmail($_POST["email"]);

        $sessionFacade->inserirCliente($cliente);

        $banco->desconecta();         header("location: cadastrarCliente.php?msg=OPERAÇÃO REALIZADA COM SUCESSO");      } catch(Exception $e) {

Page 12: Construindo uma Arquitetura de Desenvolvimento em PHP 5

        $banco->desconecta();         header("location: cadastrarCliente.php?msg=".$e->getMessage());      }

}

function mostrarClientes() {      $banco = new BancodeDados("../../../sistema/siscliente/conexao.xml");      $sessionFacade = new SessionFacade($banco);

     try {         $banco->conecta();

        $_SESSION["clientes"] = $sessionFacade->recuperarClientes();

        $banco->desconecta();         header("location: mostrarClientes.php");

     } catch(Exception $e) {         $banco->desconecta();         header("location: mostrarClientes.php?msg=".$e->getMessage());      }

}           /* PARA OS MÉTODOS DE ALTERAR E EXCLUIR SEGUE O MESMO PROCEDIMENTO. */

No início, eu coloco as classes que eu irei utilizar e inicio a sessão com session_start. A primeira condição que eu analiso é se as sessões que eu irei utilizar já existem, caso não, eu as crio sendo nulas.

A segunda é verificar se existe algum request vindo de formulário que eu nomeio como "ação" (no caso, eu julgo ações ).

Para cada tipo de ação irá existir uma função para tratar da execução.

Como funciona a classe BancodeDados está explicada na segunda parte desta série de artigos. No próximo artigo veremos as entradas e saídas de dados.

Construindo uma Arquitetura de Desenvolvimento em PHP 5 - Parte 06Rogério Rodrigues (e-mail) trabalha com Desenvolvimento de Sistemas, Modelagem de Dados, Programação em PHP e Java na Agência Espacial Brasileira. Faz bacharelado em Ciência da Computação, desenvolve trabalhos free-lancer para vários tipos de serviços Web.

Olá a todos. Nesta etapa vamos criar um layout para a entrada de dados, que será um simples formulário. Será uma etapa bem curta. Lembrando que é importante que o leitor acompanhe as matérias anteriores desta série. Todas as matérias estão listadas ao final deste artigo.

Procedimento: Na pasta cliente, crie o arquivo cadastrarCliente.php.

cadastrarCliente.php

<html><body> <?php if(isset($_GET["msg"])) {      print $_GET["msg"];

Page 13: Construindo uma Arquitetura de Desenvolvimento em PHP 5

} ?>      <form method="post" action="manterCliente.php">           <input type="text" name="nome" value="nome"><br>           <input type="text" name="telefone" value="telefone"><br>           <input type="text" name="endereco" value="endereco"><br>           <input type="text" name="email" value="email"><br>           <input type="submit" name="acao" value="Cadastrar">      </form>      <a href="manterCliente.php?acao=Mostrar">mostrar Clientes</a> </body> </html>

 

Neste formulário estou colocando a ação como "Cadastrar". Ou seja, esse formulário irá acessar na manter a função cadastrar.

Procedimento: Na pasta cliente, crie o arquivo mostrarClientes.php.

mostrarClientes.php

<?phprequire_once("../../../negocio/siscliente/cliente/Cliente.class.php"); @session_start(); ?> <html><body> <?php for($i= 0; $i < sizeof($_SESSION["clientes"]); $i++) {      print "nome: ".$_SESSION["clientes"][$i]->getNome();      print "<br>"; } ?> </body> </html>

 

Nesta página eu incluo a classe que será usada e faço um laço para mostrar os resultados que estão na sessão.

No próximo e último artigo desta série farei uma explicação geral de como e quando usar outros design patterns que podem ser utilizadas, aplicação em ambiente corporativo, ganhos e perdas, dentre outros.

Até mais!