Design Patterns e o PHP

Salve!

Quem já ouviu falar de design patterns e que programa em PHP ? Melhor: quem que programa em PHP e está utilizando qualquer uma das patterns mais conhecidas ?

Isso não é nada espantoso! Os programadores PHP em sua grande parcela ainda não acordaram para a nova realidade: código mais extensível e pensado. Nunca falei aqui, mas acho que o PHP tem um defeito grave: ser super simples. Isso estragou, em partes a fama da linguagem.

Vamos a um exemplo: duelo. Java Vs PHP.

Java: Hello world no shell

JAVA:
  1. class HelloWorld {
  2.      public static void main(String[] args) {
  3.           System.out.println("Hello World!");
  4.      }
  5. }

PHP procedural

PHP:
  1. echo 'Hello world';

PHP O.O

PHP:
  1. class HelloWorld {
  2.      public function __construct() {
  3.          echo 'HelloWorld';
  4.      }
  5. }
  6.  
  7. $hw = new HelloWorld();

O que é mais fácil ? PHP ou Java ? PHP procedural ou PHP O.O ? Essa facilidade fez com que várias aplicações inseguras e mal pensadas infestassem a rede, causando uma rejeição do PHP por parte de vários Clientes e com isso, empresas de desenvolvimento de software. Isso é ruim para a linguagem, ruim para o profissional sério e ruim para o cliente que terá que pagar mais caro por uma tecnologia como o Java.

Hélio, tá, mas onde entra os design patterns nessa sua conversa mole ? Ok, até o momento eu tangenciei o tema, mas veja que para existir Pattern é ideal que haja Programação Orientada a objetos com tudo que temos direito.

Design patterns nada mais é que um conjunto de conceitos que visa auxiliar na resolução de um problema comum entre os programadores de verdade.

E dale exemplos

MVC (Model View Control - Modelo Visualização Controle) :: essa Pattern foi desenvolvida para resolver o problema da lambança de códigos, ou seja, um arquivo faz tudo: conecta no banco, traz dados, exibe na tela, pega retorno do cliente, aplica regra de negócio e salva no banco.
Imagine uma aplicação como E-commerce feita desta forma! Loucura hein! Falando em lambança, encontrei recentemente em um dos projetos que assumi, um arquivo executa.php. Já ouviu falar dele ? O "faz tudo" ? Não ? Assunto para outro post!

Então, como eu ia dizendo: para resolver o problema de manter tudo nas "costas" de uma mesma aplicação, foi pensado e desenvolvido esse modelo MVC onde a aplicação fica separada em camadas. Na camada mais baixa, fica o modelo, que faz a interação com o servidor de banco de dados, sistema de arquivos e etc.; Depois temos a classe que processa os dados recebidos pelo usuário e se passar por checagens simples é entregue a "Model"; e por fim, temos a View que nada mais é do que o HTML que o usuário vê, sem PHP, sem CSS sem Javascript misturado.

Criando um diagrama bobo temos:

Banco de dados -> Model -> Controller -> View

View: Usuário clica no botão submit com o campo Nome preenchido.
Controller recebe esse formulário. Verifica se o nome tá setado (sem checar seu valor). Setado ? Ok, manda para a model.
Model recebe e aplica a regra de negócio: no exemplo, o nome precisa ter pelo menos 3 caracteres. Tem ? Ok, pega o poll de conexão com o banco de dados e salva.
Retorna "true" para a Controller que exibe uma mensagem de "Sucesso" na View

DAO: (Data Access Object) :: Essa Pattern tem como objetivo separar a Model em dois: regra de negócio do acesso ao banco de dados. No nosso exemplo anterior, a Usuario.php receberia da UsuarioController.php o dado e a mesma aplicaria a regra de negócio. Após estar ok, a Usuario.php enviaria o status de "ok, pode gravar" para o UsuarioDao.php e este gravaria a informação no banco (verificando se o nome não existe por exemplo) e retornaria a informação de "true" para nosso Usuario.php.
Veja que ela tem como objetivo deixar a Model mais limpa e legível à manter regra de negócio e acesso ao banco tudo junto.

Factory Pattern (Fábrica) :: tem por objetivo englobar vários recursos dentro de um mesmo método usando os blocos de condição "if" ou "switch". Exemplo:

PHP:
  1. class Usuario {
  2.      public function Pesquisa() {
  3.           switch($p) {
  4.                case is_numeric($p->Id):
  5.                     // Faz a pesquisa tomando como base o ID do cliente
  6.                     break;
  7.                
  8.                case (strlen($p->Nome)> 3):
  9.                     // Faz a pesquisa tomando como base o Nome do cliente
  10.                     break;
  11.           }
  12.      }
  13. }

Veja que no exemplo o método Pesquisa() é um só mas dependendo do tipo de informação que ele recebe, executa uma ação diferente. Isso é a Pattern Factory, novamente resolvendo outro problema usando conceitos simples. Uma outra forma de resolver o mesmo problema seria criando vários métodos PesquisaId() PesquisaNome(), porém, estariamos deixando de lado a Pattern Factory.

Singleton :: essa Pattern tem como objetivo evitar que uma mesma variável, poll de conexão e etc., ocupe mais espaço na memória. Vamos a um exemplo:

Singleton - Pattern

No desenho que criei no Gimp, ao conectar com o banco é alocado certo endereço da memória para ele. Caso eu faça outra requisição de conexão, ao invés de alocar outro endereço de memória, ele vai usar o mesmo endereço. Pense em algo fixo. Posso fazer "n" requisições que ele sempre usará o mesmo espaço que foi alocado inicialmente.

A mágina está no public static $Con. Estou definindo que o $Con será estático.
Abaixo, o script que está na imagem:

PHP:
  1. <?php
  2.  
  3. class BancoDados {
  4.  
  5.     public static $Con = null;
  6.              private function __construct() { }
  7.  
  8.     /**
  9.      * Abre uma conexão com o MySQL
  10.      */
  11.     public function Conecta() {
  12.                          if (self::$Con instanceof PDO) return self::$Con;
  13.  
  14.         self::$Con = new PDO("mysql:host=" . SERV .
  15.                     ";dbname=" . NAME . "",
  16.                     USER,
  17.                     PASS
  18.                 );
  19.  
  20.         return self::$Con;
  21.     }
  22. }
  23. ?>

Caso tenha interessado o assunto, você poderá pesquisar outras diversas Patterns que propõem solução para vários outros "problemas" que temos diariamente. Esse foi apenas um panorama geral sobre Design Patterns.



1 comentário para “Design Patterns e o PHP”

  1. nixcad says:

    Deixa eu puxar um pouco para o meu lado ;-)

    Python procedural:

    print ‘Hello World’

    Python O.O:

    class HelloWorld:
    def __init__(self):
    print ‘Hello World’

    c = HelloWorld()

    No programo para web, mas no acredito que a facilidade e clareza de sintaxe numa linguagem seja um problema. Foi o que me fez largar de Java e ir para Python.

Comente !