Padrões Criacionais do GoF: Builder, Prototype e Singleton — a continuação que fecha o ciclo

Por
Publicado em
8 min. de leitura

Fala aí, Padawan! Se no artigo anterior nós exploramos Abstract Factory e Factory Method, agora chegou a hora de continuar essa trilha dos padrões criacionais com três nomes que adoram aparecer em prova e também no mundo real: Builder, Prototype e Singleton. Eles pertencem à mesma família de padrões do GoF, mas cada um resolve um problema diferente no processo de criação de objetos. Este texto funciona como um segundo artigo, em sequência ao material anterior sobre padrões criacionais.

Quando a banca fala de padrões criacionais, ela quer saber se você entendeu uma ideia central: criar objetos parece simples, mas pode virar uma bagunça quando o sistema cresce. Às vezes o objeto é complexo demais para ser montado de uma vez; às vezes você quer copiar um objeto já existente sem reconstruir tudo; e em outras situações você quer garantir que só exista uma única instância de uma classe em toda a aplicação. É exatamente aí que entram Builder, Prototype e Singleton.

Antes de mergulhar em cada padrão, guarda esta visão geral, Padawan: Builder é usado quando a construção do objeto acontece em etapas; Prototype é usado quando você quer criar novos objetos por clonagem de um objeto existente; e Singleton é usado quando você quer garantir que exista apenas uma instância de uma classe. Em prova, essa distinção costuma valer ponto fácil, porque a banca troca os conceitos de propósito para confundir quem decorou sem entender.

Vamos começar pelo Builder. Esse padrão é muito útil quando um objeto possui muitos atributos, várias configurações possíveis ou um processo de montagem em partes. Pense em um relatório, uma requisição HTTP complexa, um carro com vários componentes ou até um objeto de configuração de sistema. Em vez de criar tudo com um construtor gigante e horroroso, você usa um Builder para montar o objeto passo a passo.

Em linguagem simples: o Builder separa a construção do objeto da sua representação final. Ou seja, você não precisa instanciar tudo de uma vez só com um monte de parâmetro no construtor. Isso melhora a legibilidade, reduz erros e facilita a criação de variações do mesmo objeto. A banca gosta muito da frase clássica: o Builder separa a construção de um objeto complexo de sua representação, permitindo criar diferentes representações usando o mesmo processo de construção.

Imagine, por exemplo, uma classe Pedido com campos como cliente, endereço, forma de pagamento, itens, cupom e observações. Sem Builder, talvez você acabasse com um construtor cheio de parâmetros, daqueles que ninguém entende depois de duas semanas. Com Builder, você pode montar o objeto de forma organizada: primeiro define o cliente, depois o endereço, depois os itens, e por fim gera o pedido. Isso torna o código mais claro e menos propenso a erro.

Veja um exemplo simples em Java:

Agora o uso:

Linha a linha, Padawan: a classe Builder vai acumulando os dados do objeto; cada método retorna o próprio Builder com return this, o que permite o encadeamento das chamadas; e o método build() cria de fato o objeto final. Isso é muito cobrado porque mostra um padrão elegante para evitar construtores telescópicos, que são aqueles construtores enormes com parâmetros demais.

Agora vem uma pegadinha clássica de concurso: Builder não é o padrão que cria famílias de objetos relacionados. Isso é Abstract Factory. Builder também não delega a criação para subclasses, como o Factory Method. O foco dele está na montagem gradual de um objeto complexo. Se a prova falar em “construção passo a passo”, “objeto complexo”, “separar construção e representação”, acenda o alerta: provavelmente é Builder.

Vamos para o Prototype. Esse padrão tem uma ideia bem interessante: em vez de criar um objeto do zero, você usa um objeto já existente como modelo e cria uma cópia dele. É como tirar uma xerox de um objeto já pronto. Isso é útil quando a criação do objeto é cara, demorada ou complexa, ou quando você quer preservar uma configuração base e gerar variações a partir dela.

O Prototype é muito associado ao conceito de clonagem. Em termos de prova, essa é a palavra-chave. O padrão define que novos objetos podem ser criados copiando um objeto protótipo existente, em vez de instanciá-los diretamente com new e reconfigurar tudo manualmente. A banca adora colocar essa descrição para tentar fazer você marcar Factory Method ou Builder. Não caia nessa.

Vamos ver um exemplo simples em Java:

Perceba a lógica: o objeto original serve como protótipo. A cópia nasce a partir dele. Depois disso, você pode ajustar alguns detalhes, como fizemos mudando o título. Na prática, isso economiza esforço quando vários objetos compartilham uma configuração inicial parecida. Em provas, fique atento aos termos cópia, clone, duplicação de objeto, modelo base e instanciação a partir de protótipos.

Mas aqui entra um detalhe técnico importante: existe a diferença entre cópia rasa e cópia profunda. A cópia rasa, também chamada de shallow copy, replica o objeto principal, mas pode continuar apontando para os mesmos objetos internos. Já a cópia profunda, ou deep copy, clona também os objetos internos, gerando independência total. Algumas bancas gostam de explorar isso, especialmente quando a questão sai do nível puramente conceitual e entra num contexto mais técnico de implementação.

Agora vamos ao famosíssimo Singleton, talvez o padrão mais conhecido — e também um dos mais polêmicos. A ideia dele é simples: garantir que uma classe tenha apenas uma instância e fornecer um ponto global de acesso a ela. Isso costuma ser usado em classes de configuração, log, cache centralizado, gerenciadores ou controladores de recursos compartilhados.

Veja um exemplo clássico em Java:

Uso:

Linha a linha: o construtor é private, o que impede que outras classes usem new Configuracao(); a classe mantém uma variável estática com sua única instância; e o método getInstancia() devolve essa instância, criando-a apenas se ainda não existir. Esse é o coração do Singleton. Veja o código de uso, as duas variáveis recebem a mesma instância, provo isso com o uso da vaiável id, que foi configurada em um objeto, mas é refletida nos dois. 

Em prova, o enunciado costuma trazer ideias como: “uma única instância”, “acesso global controlado”, “objeto compartilhado”, “evitar múltiplas instâncias”. Tudo isso aponta para Singleton. Mas tem pegadinha: a banca pode misturar Singleton com “variável global” ou com “classe estática”. Não é a mesma coisa. O Singleton continua sendo um objeto, só que com controle rígido de instanciação.

Vamos consolidar a comparação: Builder monta objetos complexos em etapas; Prototype cria novos objetos copiando um modelo existente; Singleton garante uma única instância de uma classe. Repare como os três são criacionais, mas lidam com dores bem diferentes. Builder pensa na forma de construção. Prototype pensa no reaproveitamento via cópia. Singleton pensa no controle de quantidade de instâncias.

Se você quiser ligar este artigo ao anterior, a visão fica ainda mais forte. Factory Method e Abstract Factory tratam muito de quem cria e qual família de objetos será criada. Já Builder trata de como o objeto é montado, Prototype trata de como o objeto é copiado, e Singleton trata de quantas instâncias podem existir. Essa comparação é excelente para revisar tudo em bloco e não confundir os padrões na hora da prova. 

Bora materializar isso? Agora o ideal é resolver questões e treinar a identificação da palavra-chave escondida no enunciado.

CESPE – 2010 – SERPRO – Analista Desenvolvimento de Sistemas

Julgue os itens seguintes referentes a padrões de projeto.

Padrões de criação, como singleton e prototype, envolvem necessariamente a instanciação de um ou mais objetos, sendo que, no padrão singleton, o controle sobre a instanciação é cedido ao cliente do padrão, o que não ocorre no padrão prototype.

Gabarito: FALSO.

Justificativa:
Falso porque a afirmativa erra justamente ao dizer que, no padrão Singleton, o controle sobre a instanciação é cedido ao cliente. No Singleton ocorre o oposto: a própria classe controla sua única instanciação, normalmente por meio de construtor privado e de um método estático de acesso, como getInstancia(). Ou seja, o cliente não cria livremente o objeto; ele apenas acessa a instância já controlada pela própria classe. Esse é exatamente o ponto central do padrão Singleton. 

Já o Prototype também é um padrão criacional, mas sua lógica é diferente: ele permite criar novos objetos por clonagem de um objeto existente, usando um protótipo como modelo. Então a questão mistura corretamente a ideia geral de que ambos são padrões de criação, mas erra ao inverter a responsabilidade de controle da instanciação no caso do Singleton. 

Em linguagem de prova, guarda assim, Padawan:
Singleton = a classe controla a única instância.
Prototype = novos objetos são criados a partir da cópia de um protótipo.

Essa forma de resposta segue o mesmo estilo do material anexado, com item + julgamento + justificativa objetiva.


ESAF – 2012 – CGU – Analista de Finanças e Controle – prova 3 – Desenvolvimento de Sistemas da Informação

O padrão de projeto singleton é usado para restringir

Alternativas

A) a instanciação de uma classe para objetos simples.

B) a instanciação de uma classe para apenas um objeto.

C) a quantidade de classes

D) as relações entre classes e objetos.

E) classes de atributos complexos.

Gabarito: B

Justificativa:
O padrão de projeto Singleton é utilizado para restringir a instanciação de uma classe a apenas um único objeto. Essa é a ideia central desse padrão: garantir que exista uma única instância da classe durante a execução do sistema e disponibilizar um ponto global de acesso a ela.

Vamos eliminar as demais, Padawan:

A) Incorreta. O Singleton não restringe a classe a objetos simples, mas sim a uma única instância, independentemente da complexidade do objeto.

C) Incorreta. O padrão não limita a quantidade de classes do sistema.

D) Incorreta. Essa alternativa fala de relações entre classes e objetos, o que não representa o objetivo do Singleton.

E) Incorreta. O Singleton não tem relação com atributos complexos da classe.

Resumo para prova:
Singleton = uma classe, uma única instância.


CESPE – 2009 – INMETRO – Analista Executivo em Metrologia e Qualidade – Desenvolvimento de Sistemas – Parte II

Julgue os itens que se seguem a respeito dos padrões de desenho e outras técnicas para reúso de software.

Uma das vantagens do padrão Prototype é o reúso de memória possível por meio do compartilhamento de vários objetos por meio de múltiplas interfaces. 

Item: FALSO.

Justificativa:
A afirmativa está incorreta porque atribui ao padrão Prototype uma característica que não é sua. O Prototype é um padrão criacional cujo objetivo principal é permitir a criação de novos objetos a partir da clonagem de um objeto protótipo já existente. Em outras palavras, ele facilita a criação de objetos quando copiar um modelo pronto é mais vantajoso do que instanciar tudo do zero.

A questão erra ao falar em reúso de memória por meio do compartilhamento de vários objetos por múltiplas interfaces. Essa descrição não corresponde ao Prototype. Esse tipo de ideia está muito mais associado a estratégias de compartilhamento de estrutura para economia de memória, como ocorre no padrão Flyweight, que busca justamente reduzir o consumo de memória ao compartilhar partes comuns entre vários objetos.

Assim, o Prototype está relacionado à clonagem de objetos, e não ao compartilhamento de memória entre vários objetos por múltiplas interfaces.

Resumo para prova, Padawan:
Prototype = criação por clonagem.
Flyweight = compartilhamento para economia de memória.


CESPE / CEBRASPE – 2021 – SERPRO – Analista – Especialização: Desenvolvimento de Sistemas

A respeito de padrões de criação, julgue o item subsecutivo.

O padrão Prototype cria novos objetos a partir da cópia de quaisquer objetos, sem aproveitar o estado do objeto copiado.

Gabarito: FALSO.

Justificativa:
A afirmativa está errada porque o padrão Prototype cria novos objetos a partir da cópia de um objeto já existente, aproveitando justamente o estado desse objeto copiado. Esse é o núcleo do padrão: usar um objeto protótipo como modelo para gerar outro objeto semelhante, evitando reconstruir tudo do zero.

Quando a questão diz “sem aproveitar o estado do objeto copiado”, ela contradiz a própria essência do Prototype. Ao clonar um objeto, os dados já configurados no objeto original são reaproveitados na criação do novo objeto. Depois da cópia, claro, o novo objeto pode até sofrer ajustes ou personalizações, mas ele nasce a partir do estado do protótipo.

Em linguagem de prova, guarda assim, Padawan:
Prototype = criação por clonagem, com reaproveitamento do estado do objeto original.

Se não houvesse aproveitamento do estado do objeto copiado, não faria sentido falar em Prototype, porque a vantagem desse padrão está justamente em usar um objeto já pronto como base para gerar novos objetos.


CESPE – 2017 – SEDF – Analista de Gestão Educacional – Tecnologia da Informação

Julgue o item a seguir, a respeito de padrões de projetos.

O isolamento dos códigos de construção e representação é um dos objetivos do padrão builder.

Gabarito: CERTO.

Justificativa:
A afirmativa está correta porque um dos principais objetivos do padrão Builder é justamente separar o processo de construção de um objeto da sua representação final. Em termos mais simples, o padrão isola a lógica de montagem do objeto, permitindo que esse processo aconteça de forma organizada e independente do resultado final que será gerado.

Essa separação é importante quando estamos diante de objetos complexos, com muitos atributos ou com montagem feita em várias etapas. Em vez de concentrar toda a criação em um construtor enorme e confuso, o Builder distribui essa construção de maneira mais clara, facilitando o entendimento, a manutenção e até a criação de diferentes representações a partir do mesmo processo de construção.

Em linguagem de prova, Padawan, guarda assim:
Builder = separa construção e representação.


CESPE – 2013 – TCE-RO – Analista de Informática

Julgue os itens subsequentes a respeito dos padrões de projeto.

O uso do padrão Builder tem a vantagem de permitir acesso controlado à instância de uma classe, uma vez que ele encapsula a classe, criando um ponto global único de acesso.

Gabarito: FALSO.

Justificativa:
A afirmativa está incorreta porque ela atribui ao padrão Builder uma característica que, na verdade, pertence ao padrão Singleton. O Builder tem como objetivo principal separar o processo de construção de um objeto da sua representação final, facilitando a criação de objetos complexos em etapas. Ele não foi criado para controlar a quantidade de instâncias de uma classe nem para fornecer um ponto global único de acesso.

Quando a questão fala em “acesso controlado à instância” e “ponto global único de acesso”, ela está descrevendo exatamente a ideia do Singleton. Nesse padrão, a própria classe controla sua instanciação para garantir que exista apenas um único objeto, normalmente oferecendo um método estático para acesso a essa instância.

Portanto, a questão está errada por confundir os objetivos dos padrões:

Builder = separa construção e representação.
Singleton = instância única com ponto global de acesso.

Essa troca de conceitos é uma pegadinha clássica de prova, Padawan.

Por
Publicado em
8 min. de leitura