Atividade 02: Singleton
Exercício 1: Aplicações
Seção intitulada “Exercício 1: Aplicações”Para cada cenário abaixo, indique se o padrão Singleton é apropriado ou não e justifique em 2–3 frases.
- Um serviço de configurações da aplicação que carrega propriedades de um arquivo (
application.properties) e é lido por vários módulos de um sistema web. - Um componente responsável por gerenciar conexões HTTP para chamadas a APIs externas, onde diferentes partes do sistema podem precisar de configurações de timeout e autenticação distintas.
- Um logger central que registra eventos da aplicação em arquivo/console, usado por dezenas de classes diferentes.
- Uma classe que representa o usuário autenticado atual em um sistema web com múltiplos usuários acessando simultaneamente.
- Um cache em memória compartilhado entre vários serviços do back-end, que armazena dados frequentemente lidos do banco.
Para cada item, responda:
- “Faz sentido usar Singleton” ou “Não faz sentido usar Singleton”.
- Explique rapidamente o porquê (unicidade, escopo, concorrência, testes, etc.).
Exercício 2: Analogia
Seção intitulada “Exercício 2: Analogia”Crie uma analogia própria para explicar o padrão Singleton para alguém que não é da área de TI.
- Descreva uma situação do mundo real em que:
- exista algo que deve ser único,
- e que seja acessado por várias pessoas/locais diferentes.
- Explique por que essa analogia representa bem:
- a ideia de única instância,
- e de ponto global de acesso.
- Indique também uma limitação da sua analogia (algo que não encaixa perfeitamente com o padrão).
Exercício 3: Anti-pattern
Seção intitulada “Exercício 3: Anti-pattern”Considere o código Java abaixo, usado em uma aplicação desktop de vendas:
public class CarrinhoDeComprasSingleton {
private static CarrinhoDeComprasSingleton instancia;
private List<Item> itens = new ArrayList<>();
private CarrinhoDeComprasSingleton() { }
public static CarrinhoDeComprasSingleton getInstancia() { if (instancia == null) { instancia = new CarrinhoDeComprasSingleton(); } return instancia; }
public void adicionarItem(Item item) { itens.add(item); }
public List<Item> getItens() { return itens; }
// ...outros métodos de regras de negócio...}Em uma versão futura, essa aplicação passa a ser multiusuário (cada cliente loga com sua conta, possivelmente em paralelo).
Responda:
- Por que esse uso de Singleton é um problema arquitetural nesse cenário?
- Que tipo de bugs ou comportamentos estranhos podem acontecer quando vários usuários utilizarem o sistema ao mesmo tempo?
- Sugira outra abordagem de design para o carrinho (sem usar Singleton) e explique, em linhas gerais, como as instâncias deveriam ser gerenciadas.
Exercício 4: Exemplo real
Seção intitulada “Exercício 4: Exemplo real”Acesse o seguinte arquivo em um projeto open source:
- Projeto: Apache Spark
- Arquivo:
JavaRecoverableNetworkWordCount
O Apache Spark é um framework de processamento distribuído de dados em larga escala. No arquivo indicado, há uma classe que implementa um contador de palavras que pode ser recuperado após falhas.
Responda:
- Procure explicar, em linhas gerais, quais funcionalidades estão implementadas nesse exemplo.
- Quais as classes presentes nesse arquivo que podem ser consideradas Singletons, como vimos em aula? Justifique sua resposta.
- As soluções apresentadas no código são thread-safe? Explique o porquê.
- Porque há duas verificações de
if (instance == null)no métodogetInstance()? Podemos considerar essa estratégia desperdício de recursos? Justifique sua resposta.
Exercício 5: Implementação
Seção intitulada “Exercício 5: Implementação”Imagine que você foi contratado para criar um Sistema Central de Alertas de Emergência para diferentes órgãos de segurança:
- Polícia
- Bombeiros
- SAMU
Cada órgão possui seu próprio módulo no sistema, mas todos precisam acessar o mesmo centro de controle para:
- enviar alertas (por exemplo: acidente, incêndio, assalto),
- receber mensagens já registradas no sistema (histórico de alertas).
Sua missão
Seção intitulada “Sua missão”Implemente, em Java, um sistema em que exista apenas um “central de alertas” na aplicação inteira, usando o padrão Singleton.
- Crie uma classe
CentralDeAlertasque seja um Singleton:- Uma estrutura interna (por exemplo,
List<String> mensagens) para armazenar os alertas enviados. - Métodos, por exemplo:
public void enviarAlerta(String orgao, String mensagem)que adiciona uma nova mensagem ao sistema, incluindo o nome do órgão que enviou.public List<String> getAlertas()– retorna a lista de mensagens registradas.
- Uma estrutura interna (por exemplo,
- Implemente três classes representando os órgãos:
PoliciaBombeirosSamu
- Cada órgão deve:
- Obter a instância da
CentralDeAlertassem usarnew; - Ter um método, por exemplo,
enviarAlerta(String mensagem)que encaminha a mensagem para aCentralDeAlertas. - Ter um método para listar todos alertas registrados na central.
- Obter a instância da
- Crie uma classe de teste, por exemplo
Main, que:- Crie objetos de
Policia,BombeiroseSamu. - Faça cada órgão enviar pelo menos um alerta (mensagens diferentes).
- Liste os alertas a partir de pelo menos dois órgãos diferentes e mostre que todos veem o mesmo histórico (com as mensagens de todos).
- Comprove, se quiser, imprimindo o
hashCode()da instância deCentralDeAlertasem partes diferentes do código para mostrar que é sempre o mesmo objeto.
- Crie objetos de
- Adicione um
README.mdao projeto explicando:- Por que faz sentido que a
CentralDeAlertasseja um Singleton nesse contexto? - Que problemas poderiam acontecer se cada órgão tivesse sua própria instância de central?
- Sua implementação é thread-safe? Se sim, demonstre como funciona no código. Se não, o que poderia ser feito para torná-la segura em um cenário com múltiplas threads (por exemplo, vários módulos disparando alertas ao mesmo tempo)?
- Por que faz sentido que a