Os padrões de projeto são fundamentais na criação de software bem estruturado e fácil de manter. Entre eles, o Singleton e o Observable são frequentemente utilizados em cenários que exigem controle de estado global e comunicação entre diferentes partes do sistema. Neste artigo, vamos explorar como esses dois padrões funcionam, quando utilizá-los, suas diferenças e fornecer exemplos práticos de como implementá-los.
O que é o Singleton?
O Singleton Pattern é um padrão de design criacional que assegura que uma classe tenha apenas uma instância e fornece um ponto global de acesso a essa instância. Esse padrão é útil quando você precisa de um objeto único em toda a aplicação, como em configurações globais, conexão com banco de dados, ou gerenciamento de logs.
Como Funciona o Singleton?
A principal característica do Singleton é que ele restringe a instância da classe a um único objeto, garantindo que todas as requisições de instância retornem o mesmo objeto. Para isso, o padrão normalmente utiliza um método estático que cria a instância apenas quando ela é solicitada pela primeira vez, garantindo a criação única e o uso do objeto em todo o sistema.
No diagrama abaixo, a sequência mostra como a instância do Singleton é criada e acessada, garantindo que seja única.
O diagrama de sequência do Singleton ilustra o fluxo de interação entre o cliente e a classe Singleton. O processo começa com o cliente chamando o método estático getInstance() para obter a instância do Singleton. Se a instância ainda não foi criada, o Singleton cria uma nova instância e a retorna. Quando o cliente chama novamente o método getInstance(), a mesma instância é retornada, garantindo que exista apenas uma instância do objeto Singleton durante toda a execução do programa.
Exemplo de Uso - Singleton em TypeScript
class Singleton {
private static instance: Singleton;
private constructor() { }
// Método para acessar a instância única
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
public showMessage(): string {
return "Esta é a única instância!";
}
}
// Uso do Singleton
const instance1 = Singleton.getInstance();
console.log(instance1.showMessage()); // "Esta é a única instância!"
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
Quando Usar o Singleton?
- Configurações globais: quando você precisa de uma instância única para armazenar configurações de sistema, como variáveis de ambiente.
- Gestão de conexões: por exemplo, para gerenciar conexões com um banco de dados ou um servidor de API.
- Gerenciamento de recursos: quando é necessário controlar o acesso a um recurso exclusivo, como um logger ou cache.
O que é o Observable?
O Observable Pattern é um padrão de design comportamental que define uma dependência de um-para-muitos entre objetos. Ou seja, quando o estado de um objeto (o "subject") muda, todos os seus dependentes (os "observers") são notificados automaticamente. Este padrão é muito utilizado em sistemas onde eventos e mudanças de estado precisam ser propagados entre diversos componentes, como interfaces gráficas ou sistemas de monitoramento.
Como Funciona o Observable?
O padrão Observable permite que objetos "observem" as mudanças de estado de um objeto e reajam a essas mudanças. O padrão se baseia em três componentes principais:
- Subject: o objeto que mantém o estado e envia notificações aos observers.
- Observer: objetos que estão interessados nas mudanças de estado do Subject.
- Subscription: um mecanismo que permite ao Observer se inscrever ou cancelar a inscrição nas notificações do Subject.
O diagrama de sequência do Observable demonstra como o padrão funciona com múltiplos observadores. O Subject (ou objeto observado) notifica todos os Observers registrados quando ocorre uma mudança de estado. Cada Observer reage à notificação, realizando as ações necessárias com base nas informações recebidas. O processo de notificação é propagado de forma que todos os observadores sejam atualizados simultaneamente, mantendo-os sincronizados com o estado do Subject. Esse padrão é útil quando há múltiplos componentes ou partes do sistema que precisam ser informados sobre mudanças no estado de um objeto.
Exemplo de Uso - Observable em TypeScript
// Interface Observer
interface Observer {
update(message: string): void;
}
// Classe Subject
class Observable {
private observers: Observer[] = [];
// Método para adicionar observers
public addObserver(observer: Observer): void {
this.observers.push(observer);
}
// Método para remover observers
public removeObserver(observer: Observer): void {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
// Método para notificar observers
public notifyObservers(message: string): void {
this.observers.forEach(observer => observer.update(message));
}
}
// Classe Observer concreta
class ConcreteObserver implements Observer {
private name: string;
constructor(name: string) {
this.name = name;
}
public update(message: string): void {
console.log(`${this.name} recebeu a mensagem: ${message}`);
}
}
// Uso do Observable
const observable = new Observable();
const observer1 = new ConcreteObserver("Observer 1");
const observer2 = new ConcreteObserver("Observer 2");
observable.addObserver(observer1);
observable.addObserver(observer2);
observable.notifyObservers("Mudança no sistema!");
observable.removeObserver(observer1);
observable.notifyObservers("Nova mudança!");
Quando Usar o Observable?
- Eventos em interfaces gráficas: para reagir a cliques de botões, mudanças de campos, ou atualizações de tela.
- Notificação de mudanças de estado: quando diversos componentes precisam ser informados sobre alterações em um objeto.
- Modelagem de fluxo de dados reativo: em sistemas onde há propagação de dados ou eventos entre múltiplos sistemas, como em aplicações baseadas em eventos.
Diferenças entre Singleton e Observable
Embora ambos os padrões sirvam para gerenciar objetos de forma controlada, suas finalidades e comportamentos são bem diferentes:
Característica | Singleton | Observable |
---|---|---|
Objetivo | Garantir que uma classe tenha apenas uma instância. | Notificar múltiplos objetos sobre mudanças de estado. |
Instância | Apenas uma instância é criada e compartilhada. | Vários objetos podem ser observadores de um único sujeito. |
Uso principal | Gerenciamento de recursos exclusivos. | Notificação de eventos e mudanças de estado. |
Exemplo de uso | Gerenciamento de logs ou configuração global. | Atualização de interfaces gráficas ou propagação de eventos. |
Conclusão
Os padrões Singleton e Observable são fundamentais em diversas situações no desenvolvimento de software. O Singleton é ideal quando precisamos garantir uma única instância de uma classe em toda a aplicação, enquanto o Observable é útil para notificar e gerenciar interações entre múltiplos objetos com base nas mudanças de estado.
Ao escolher entre esses padrões, considere as necessidades do seu projeto. Use o Singleton quando a unicidade de uma instância for crucial para a aplicação, e utilize o Observable quando o seu sistema precisar reagir a mudanças de estado ou eventos.
Top comments (0)