DEV Community

Cover image for Singleton ou Observable? A Escolha Errada Pode Custar Sua Promoção!
Cláudio Filipe Lima Rapôso
Cláudio Filipe Lima Rapôso

Posted on

Singleton ou Observable? A Escolha Errada Pode Custar Sua Promoção!

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.

Diagrama de Sequência do Singleton

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. Subject: o objeto que mantém o estado e envia notificações aos observers.
  2. Observer: objetos que estão interessados nas mudanças de estado do Subject.
  3. Subscription: um mecanismo que permite ao Observer se inscrever ou cancelar a inscrição nas notificações do Subject.

Diagrama de Sequência do Observable

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!");
Enter fullscreen mode Exit fullscreen mode

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.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay