Logo

dev-resources.site

for different kinds of informations.

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

Published at
1/10/2025
Categories
javascript
programming
designpatterns
architecture
Author
sertaoseracloud
Author
15 person written this
sertaoseracloud
open
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.

architecture Article's
30 articles in total
Favicon
Mastering Essential Software Architecture Patterns: A Comprehensive Guide🛠️, Part 6
Favicon
MVVM directory structure for larger project
Favicon
Solving Circular Dependencies: A Journey to Better Architecture
Favicon
微前端
Favicon
Como redes peer-to-peer funcionam?
Favicon
Things About Contexts in Front-end Projects
Favicon
The Myth of the 10x Software Developer
Favicon
[Boost]
Favicon
How to Design a Secure and Scalable Multi-Region Architecture on AWS
Favicon
Token Bucket Rate Limiter (Redis & Java)
Favicon
Streamlining Data Flow in Angular: The Power of the Adapter Pattern 🔄
Favicon
Cqrs
Favicon
Why Schema Compatibility Matters
Favicon
Абстракции vs. привязка к технологии
Favicon
Understanding the Essential Elements of a Well-Designed CISC Architecture for Modern Computing
Favicon
Things About Modules in Front-end Projects
Favicon
The first part of this MASSIVE series about software architecture patterns is OUT!! please check it out!!
Favicon
Designing Context for New Modules in HyperGraph
Favicon
Patterns of Directory Structure in Front-end Projects
Favicon
Mastering Backend Node.js Folder Structure, A Beginner’s Guide
Favicon
What Makes a Good Cloud Architect?
Favicon
Optimizing Module Development in HyperGraph: A Minimalist Approach
Favicon
The Future of Architecture: Where Innovation Meets Sustainability
Favicon
Top AI Tools for Architects and Interior Designers
Favicon
Singleton ou Observable? A Escolha Errada Pode Custar Sua Promoção!
Favicon
Do Local ao Global: A Migração para Azure que Aumentou Nossa Eficiência e Segurança
Favicon
Your API Doesn’t Always Need to Be a Product
Favicon
The Future of Architecture is Being Built by Robots
Favicon
The Role of Serverless Architecture in Modern Website Development: Benefits and Impact
Favicon
Understanding Microservices Architecture in Full-Stack Applications

Featured ones: