Introdução aos Padrões de Projeto com PHP – Parte 2

Atenção! Essa postagem foi escrita há mais de 2 anos. Na informática tudo evolui muito rápido e algumas informações podem estar desatualizadas. Embora o conteúdo possa continuar relevante, lembre-se de levar em conta a data de publicação enquanto estiver lendo. Caso tenha sugestões para atualizá-la, não deixe de comentar!

E aí, povo! Tudo certo?

Continuando a nossa série de estudos sobre Padrões de Projeto, hoje daremos uma olhada mais aprofundada nos padrões que existem e que iremos estudar. Caso você ainda não tenha lido, dê uma olhada na primeira parte dessa série dando uma introdução aos design patterns.

Uma vez que os padrões de projeto foram desenvolvidos originalmente para suprir necessidades de software independente da linguagem, alguns autores gostam de selecionar apenas os padrões mais utilizados em determinada linguagem. Nesta série também não citarei todos os padrões da GoF porque alguns, como o Iterator, já estão implementados nativamente na linguagem (o Iterator é um foreach, por exemplo). Aproveitarei o espaço aberto por esses padrões e indicarei alguns outros que não fazem parte da GoF mas que são muito importantes de serem estudados.

Vamos dar uma olhada em como se dividem os padrões da GoF e em seguida quais serão alguns dos padrões citados mais adiante.

Padrões da Gang of Four

Criacionais

  • Abstract Factory: Fornece uma interface para criação de famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
  • Builder: Separa a construção de um objeto da sua representação, de modo que o mesmo processo de construção possa criar diferentes representações.
  • Factory Method: Define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe a ser instanciada. O Factory Method permite a uma classe postergar a instanciação às subclasses.
  • Prototype: Especifica os tipos de objetos a serem criados usando uma instância prototípica e criar novos objetos copiando este protótipo.
  • Singleton: Garante que uma classe tenha somente uma instância e fornece um ponto global de acesso para ela.

Estruturais

  • Adapter: Converte a interface de uma classe em outra interface esperada pelos clientes. O Adapter permite que certas classes trabalhem em conjunto, pois de outra forma seria impossível por causa de suas interfaces incompatíveis.
  • Bridge: Separa uma abstração da sua implementação, de modo que as duas possam variar independentemente.
  • Composite: Compõe objetos em estrutura de árvore para representar hierarquias do tipo partes-todo. O Composite permite que os clientes tratem objetos individuais e composições de objetos de maneira uniforme.
  • Decorator: Atribui responsabilidades adicionais a um objeto dinamicamente. Os decorators fornecem uma alternativa flexível a subclasses para extensão da funcionalidade.
  • Façade: Fornece uma interface unificada para um conjunto de interfaces em um subsistema. O Façade define uma interface de nível mais alto que torna o subsistema mais fácil de usar.
  • Flyweight: Usa compartilhamento para suportar grandes quantidades de objetos, de granularidade fina, de maneira eficiente.
  • Proxy: Fornece um objeto representante (surrogate), ou um marcador de outro objeto, para controlar o acesso ao mesmo.

Comportamentais

  • Chain of Responsability: Evita o acoplamento do remetente de uma solicitação ao seu destinatário, dando a mais de um objeto a chance de tratar a solicitação. Encadeia os objetos receptores e passa a solicitação ao longo da cadeia até que um objeto a trate.
  • Command: Encapsula uma solicitação como um objeto, desta forma permitindo que você parametrize clientes com diferentes solicitações, enfileire ou registre (log) solicitações e suporte operações que podem ser desfeitas.
  • Interpreter: Dada uma linguagem, define uma representação para sua gramática juntamente com um interpretador que usa a representação para interpretar sentenças nesta linguagem.
  • Iterator: Cria um iterador para interagir com os objetos, retirando a iteração das responsabilidades do próprio objeto.
  • Mediator: Define um objeto que encapsula como um conjunto de objetos interage. O Mediator promove o acoplamento fraco ao evitar que os objetos se refiram explicitamente uns aos outros, permitindo que você varie suas interações independentemente.
  • Memento: Sem violar a encapsulação, captura e externaliza um estado interno de um objeto, de modo que o mesmo possa posteriormente ser restaurado para este estado.
  • Observer: Define uma dependência um-para-muitos entre objetos, de modo que, quando um objeto muda de estado, todos os seus dependentes são automaticamente notificados e atualizados.
  • State: Permite que um objeto altere seu comportamento quando seu estado interno muda. O objeto parecerá ter mudado de classe.
  • Strategy: Define uma família de algoritmos, encapsula cada um deles e os faz intercambiáveis. O Strategy permite que o algoritmo varie independentemente dos clientes que o utilizam.
  • Template Method: Define o esqueleto de um algoritmo em uma operação, postergando a definição de alguns passos para subclasses. O Template Method permite que as subclasses redefinam certos passos de um algoritmo sem mudar sua estrutura.
  • Visitor: Representa uma operação a ser executada sobre os elementos da estrutura de um objeto. O Visitor permite que você defina uma nova operação sem mudar as classes dos elementos sobre os quais opera, criando métodos virtualmente.

Além das divisões por finalidade, os padrões de projeto possuem outro tipo de divisão. Existem padrões de classe e padrões de objeto.

Outros padrões de projeto

O fato de estes padrões não terem sido desenvolvidos pela GoF não os torna menos importantes. Inclusive muitos destes padrões você já pode ter implementado, de uma forma ou de outra, e nem ter percebido!

Os padrões que veremos a seguir são mais específicos do que os vistos anteriormente. Suas finalidades são focadas na resolução de problemas não tão genéricos e na aceleração do desenvolvimento.

Vamos dar uma olhada:

  • Table Data Gateway: Cria objetos que referenciam tabelas no banco de dados dando acesso dando acesso simplificado à elas sem a necessidade de digitar SQL.
  • Row Data Gateway: Dá acesso a um determinado registro em uma tabela do banco e permite que sejam alterados seus valores.
  • MVC: O nome deste padrão é Model-view-controller. Separa a aplicação em três camadas: banco de dados, lógica de negócio e apresentação.
  • Active Record: Deriva-se do Row Data Gateway. Mapeia uma linha de registro de uma determinada tabela no banco de dados e disponibiliza métodos de acesso, gravação e alteração para o mesmo, implementando algumas regras de negócio.
  • Data Mapper: Uma versão aprimorada do Active Record, porém com mais camadas de separação para lidar com lógicas de negócio mais complexas.
  • Lazy Load: Permite que objetos encadeados só sejam carregados quando necessário, reduzindo a carga na memória.

Conclusão

E por hoje é só, pessoal! Aproveitei esse artigo pra falar um pouquinho mais sobre alguns padrões que vamos estudar daqui pra frente e espero que tenha servido para dar uma iluminada nas ideias!
Provavelmente no próximo artigo já começaremos a colocar a mão na massa! :-)

Um abraço para todos e fiquem com Deus!