Padrões de Projeto em PHP: o que são e para que servem?
Padrões de projeto (design patterns) são soluções comprovadas para problemas típicos em programação orientada a objetos. Eles não são código pronto, mas sim modelos que podem ser adaptados para uma situação específica. Em PHP, os padrões são especialmente úteis para criar aplicações web escaláveis e de fácil manutenção.
Neste artigo, vamos analisar três padrões principais: Singleton, Factory e Observer. Para cada um, daremos exemplos reais em PHP e explicaremos em quais situações devem ser aplicados.
Por que estudar padrões em PHP?
- Simplificação do código — abordagem uniforme para resolver problemas.
- Reutilização — padrões são facilmente adaptáveis para diferentes projetos.
- Facilidade de manutenção — o código se torna compreensível para outros desenvolvedores.
- Testabilidade — o uso de padrões simplifica a escrita de unit-tests.
1. Padrão Singleton
O Singleton garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela. Em PHP, é frequentemente usado para conexão com banco de dados, logging ou configuração.
Exemplo: Classe para trabalhar com BD
<?phpclass Database { private static ?Database $instance = null; private PDO $connection;
private function __construct() { // Conexão com BD (exemplo com SQLite) $this->connection = new PDO('sqlite:example.db'); $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); }
public static function getInstance(): Database { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; }
public function getConnection(): PDO { return $this->connection; }
// Proíbe clonagem e desserialização private function __clone() {} public function __wakeup() { throw new \\Exception("Cannot unserialize singleton"); }}
// Uso$db = Database::getInstance();$pdo = $db->getConnection();?>Quando aplicar o Singleton?
- Quando é necessária exatamente uma instância da classe (ex.: conexão com BD).
- Para acesso global a um recurso (logger, cache).
- Em situações onde criar várias instâncias levaria a conflitos.
Desvantagens: viola o princípio da responsabilidade única e dificulta os testes (cria estado global).
2. Padrão Factory (Fábrica)
O Factory Method (Método Fábrica) define uma interface para criar um objeto, mas permite que as subclasses alterem o tipo do objeto criado. Isso é útil quando o tipo do objeto não é conhecido antecipadamente ou pode variar.
Exemplo: Fábrica para criar notificações
<?php// Interface para todos os tipos de notificaçãointerface Notification { public function send(string $message): void;}
// Implementações concretasclass EmailNotification implements Notification { public function send(string $message): void { echo "Enviando email: {$message}"; }}
class SMSNotification implements Notification { public function send(string $message): void { echo "Enviando SMS: {$message}"; }}
// Fábricaclass NotificationFactory { public static function create(string $type): Notification { return match ($type) { 'email' => new EmailNotification(), 'sms' => new SMSNotification(), default => throw new \\InvalidArgumentException("Tipo desconhecido: {$type}"), }; }}
// Uso$notification = NotificationFactory::create('email');$notifica