Padrões de criação: Factory, Builder e Singleton
Controle a criação de objetos de forma organizada com padrões de criação.
Padrões de criação: Factory, Builder e Singleton é uma aula grátis de PHP Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de PHP Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de PHP Academy inclui 4 aulas no total.
Controlando a criação
Os padrões de criação desacoplam o que você precisa de como isso é construído. Quando a construção é condicional, envolve várias etapas ou precisa ser centralizada, espalhar new pela base de código acopla os chamadores a classes concretas. Aqui abordamos a Fábrica (e o Método de Fábrica), o Builder para montagens complexas e o Singleton (com suas ressalvas).
Fábrica simples
Uma fábrica simples centraliza uma decisão de criação por trás de um único método. Os chamadores solicitam um tipo lógico e recebem uma instância concreta configurada, sem conhecer os nomes das classes.
<?php
interface Notifier { public function send(string $msg): string; }
final class EmailNotifier implements Notifier {
public function send(string $m): string { return "email: $m"; }
}
final class SmsNotifier implements Notifier {
public function send(string $m): string { return "sms: $m"; }
}
final class NotifierFactory {
public static function make(string $channel): Notifier {
return match ($channel) {
'email' => new EmailNotifier(),
'sms' => new SmsNotifier(),
default => throw new InvalidArgumentException($channel),
};
}
}
echo NotifierFactory::make('sms')->send('Hi'), PHP_EOL;
Método de Fábrica
O padrão Método de Fábrica adia a instanciação para as subclasses. A classe base define um algoritmo que chama um create() abstrato; cada subclasse decide qual será o produto concreto. Isso favorece o OCP: adicione um novo criador sem editar os existentes.
<?php
abstract class ReportExporter {
abstract protected function create(): string;
public function export(): string {
return 'Exported as ' . $this->create();
}
}
final class PdfExporter extends ReportExporter {
protected function create(): string { return 'PDF'; }
}
final class CsvExporter extends ReportExporter {
protected function create(): string { return 'CSV'; }
}
echo (new PdfExporter())->export(), PHP_EOL;
echo (new CsvExporter())->export(), PHP_EOL;
Fábrica Abstrata
Uma Fábrica Abstrata produz famílias de objetos relacionados que precisam ser usados em conjunto (por exemplo, uma MySqlConnection + um MySqlQueryBuilder). Ela garante que as partes sejam compatíveis, pois uma única fábrica fornece o conjunto completo. Use-a quando uma família de produtos precisar permanecer internamente consistente.
Builder: o problema
Quando um objeto precisa de muitos parâmetros opcionais, os construtores se transformam em listas ilegíveis de argumentos posicionais ou em sobrecargas em cascata, que o PHP sequer possui. O padrão Builder monta um objeto complexo passo a passo, retornando um produto final válido ao término.
Builder fluente
Um builder fluente retorna $this de cada método configurador, e então um build() produz o resultado imutável. Isso mantém o próprio produto simples e transfere a lógica de montagem para o builder.
<?php
final class Query {
public function __construct(public readonly string $sql) {}
}
final class QueryBuilder {
private string $table = '';
private array $where = [];
public function from(string $t): self { $this->table = $t; return $this; }
public function where(string $c): self { $this->where[] = $c; return $this; }
public function build(): Query {
$sql = "SELECT * FROM {$this->table}";
if ($this->where) { $sql .= ' WHERE ' . implode(' AND ', $this->where); }
return new Query($sql);
}
}
echo (new QueryBuilder())->from('users')->where('age > 18')->build()->sql, PHP_EOL;
Builder versus construtores nomeados
Para casos mais simples, os argumentos nomeados do PHP 8 e os construtores nomeados (métodos estáticos de fábrica) geralmente são melhores do que um builder completo.
- Use argumentos nomeados quando todos os dados estiverem disponíveis de uma só vez.
- Use um builder quando a montagem envolver várias etapas, for condicional ou for reutilizada em diferentes pontos de chamada.
<?php
final class Money {
private function __construct(public readonly int $cents, public readonly string $cur) {}
public static function fromDollars(float $d): self {
return new self((int) round($d * 100), 'USD');
}
public static function zero(string $cur = 'USD'): self {
return new self(0, $cur);
}
}
var_dump(Money::fromDollars(19.99)->cents); // int(1999)
Singleton
Um Singleton garante uma única instância por meio de um ponto de acesso global. Implemente-o com um construtor privado e um acessador estático. Ele é realmente útil para componentes que precisam ser únicos dentro de um processo, mas também é o padrão mais utilizado de forma indevida.
<?php
final class Config {
private static ?self $instance = null;
private array $data = ['debug' => true];
private function __construct() {}
public static function instance(): self {
return self::$instance ??= new self();
}
public function get(string $k): mixed { return $this->data[$k] ?? null; }
}
var_dump(Config::instance()->get('debug'));
var_dump(Config::instance() === Config::instance()); // true
Por que o Singleton causa problemas
Os Singletons introduzem estado global oculto: os chamadores acessam Config::instance() em vez de declararem a dependência, o que prejudica a capacidade de teste e o processamento paralelo. No PHP moderno, prefira registrar uma única instância compartilhada em um contêiner de DI (ciclo de vida de "instância única") e injetá-la. Assim, você obtém uma única instância sem o acoplamento global.
Escolhendo a ferramenta certa
- Fábrica simples/Método de Fábrica: ocultar classes concretas por trás de uma decisão de criação.
- Fábrica Abstrata: produzir famílias de produtos compatíveis.
- Builder: montar objetos complexos passo a passo.
- Singleton: último recurso; prefira serviços compartilhados gerenciados pelo contêiner.
Os quatro reduzem o acoplamento a construtores concretos, tornando o código mais fácil de estender e testar.
Fábrica baseada em registro
Uma fábrica mais dinâmica procura os criadores em um registro, permitindo que novos tipos se registrem sem editar a fábrica (OCP verdadeiro). É assim que os sistemas de plug-ins e os serializadores associam um nome de tipo a um construtor em tempo de execução.
<?php
interface Shape { public function name(): string; }
final class Circle implements Shape { public function name(): string { return 'circle'; } }
final class Square implements Shape { public function name(): string { return 'square'; } }
final class ShapeRegistry {
private array $creators = [];
public function register(string $key, callable $factory): void {
$this->creators[$key] = $factory;
}
public function create(string $key): Shape {
return ($this->creators[$key] ?? throw new InvalidArgumentException($key))();
}
}
$r = new ShapeRegistry();
$r->register('circle', fn() => new Circle());
$r->register('square', fn() => new Square());
echo $r->create('square')->name(), PHP_EOL; // square
Verificação rápida
Escolha a melhor ferramenta de criação para o cenário.
Recapitulação
Você controlou a criação de objetos com os padrões de criação: fábricas para ocultar tipos concretos e escolher famílias de produtos, builders para montar objetos complexos de forma fluente e o Singleton, com suas vantagens e desvantagens. A conclusão moderna é: prefira livremente fábricas e builders, mas substitua o Singleton pelo ciclo de vida de instância compartilhada de um contêiner de DI para manter as dependências explícitas e testáveis.
Perguntas Frequentes
A aula “Padrões de criação: Factory, Builder e Singleton” é grátis?
Sim — o texto completo de “Padrões de criação: Factory, Builder e Singleton” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de PHP Academy, atualize para CoddyKit PRO. O curso de PHP Academy inclui 4 aulas no total.
O que vou aprender em “Padrões de criação: Factory, Builder e Singleton”?
Controle a criação de objetos de forma organizada com padrões de criação. Você pratica PHP Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar PHP Academy?
Nenhuma experiência prévia é necessária. PHP Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Padrões de criação: Factory, Builder e Singleton”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de PHP Academy?
Sim. Cada aula de PHP Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Princípios SOLID na prática
- Padrões de criação: Factory, Builder e Singleton
- Padrões estruturais: Adapter, Decorator e Facade
- Padrões comportamentais: Strategy, Observer e Command