Padrão Singleton em C#: Guia Completo para Iniciantes
Implementando Observer em C# com Dependency Injection
Imagine um aplicativo de delivery: quando📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. seu pedido sai para entrega, você recebe notificações por email, SMS e no app. Como essas notificações são coordenadas? O Observer
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. Pattern é o segredo por trás dessa sincronia! Neste projeto, vamos criar um sistema de notificações usando Observer e Dependency Injection (DI) em C#, combinando padrões de design com boas práticas
🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. modernas de desenvolvimento.
// Exemplo rápido: Notificações disparando para múltiplos canais
var subject = new NotificationSubject();
subject.Attach(new EmailObserver());
subject.Attach(new SMSObserver());
subject.Notify("Seu pedido saiu para entrega!");
Tabela de Conteúdo🔗
1. O que é o Padrão Observer👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.?
2. Estrutura Geral do Projeto🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes.
3. Criando o Sujeito👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. (Subject)
4. Criando os Observadores👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. (Observers)
5. Injeção de Dependências💉 Dependency Injection: Injeção de Dependências com .NET Core!Entenda como a Injeção de Dependências no .NET Core organiza seu código, promovendo modularidade, testes eficientes e fácil manutenção. no Projeto
7. Conclusão
O que é o Padrão Observer?🔗
No Observer👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas., também chamado de “publicador/assinante”, temos duas entidades principais:
- Subject
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.: objeto que emite eventos ou notificações.
- Observers
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. (ou “assinantes”): objetos que desejam receber notificações do Subject
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas..
Quando o Subject muda de estado, todos os Observers são informados “automaticamente”. Isso evita dependências desnecessárias, deixando cada observador👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. livre para reagir do próprio jeito.
Por que usar?
- Baixo acoplamento: o Subject não precisa saber detalhes de cada Observer
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas..
- Facilidade de extensão: adicionar novos observadores
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. sem modificar o Subject.
Estrutura Geral do Projeto🔗
Nossa ideia será implementar uma classe “central de notificações” (Subject) que avisa a todos os “ouvintes” (Observers👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.) quando um evento ocorre. Exemplos no mundo real:
- Notificações de estoque de um produto
🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. que chegou.
- Atualizações sobre pedidos em um e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades.-commerce.
- Alertas
📊 Monitoramento com Prometheus: Métricas em Tempo Real!Descubra como implementar o Prometheus para monitoramento em sistemas .NET, com métricas em tempo real e dashboards inteligentes. de temperatura para sensores IoT.
Vamos organizar assim:
1. Uma interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. para o Subject
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas..
2. Uma interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. para o Observer
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas..
3. Uma implementação concreta do Subject👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas..
4. Observers👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. específicos, cada um faz algo diferente ao ser notificado.
5. Injeção de Dependências💉 Dependency Injection: Injeção de Dependências com .NET Core!Entenda como a Injeção de Dependências no .NET Core organiza seu código, promovendo modularidade, testes eficientes e fácil manutenção. para criar
📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. tudo e amarrar as instâncias.
Criando o Sujeito (Subject)🔗
Primeiro, definimos uma interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. que represente o comportamento de um “sujeito observável”. Terá métodos para adicionar
📦 List<T>: Dinamismo além dos Arrays!Descubra como utilizar List<T> em C# de forma eficiente. Aprenda a criar, manipular e otimizar listas para diferentes cenários com exemplos práticos., remover
📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. notificar observadores
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.:
public interface INotificacaoSubject
{
void AdicionarObserver(INotificacaoObserver observer);
void RemoverObserver(INotificacaoObserver observer);
void NotificarTodos(string mensagem);
}
Em seguida, criamos uma implementação concreta. Ela terá uma lista interna de observers👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. e, quando surgir algo novo, chamará cada observer para fazer algo com essa informação:
public class NotificacaoSubject : INotificacaoSubject
{
private readonly List<INotificacaoObserver> _observers = new List<INotificacaoObserver>();
public void AdicionarObserver(INotificacaoObserver observer)
{
_observers.Add(observer);
}
public void RemoverObserver(INotificacaoObserver observer)
{
_observers.Remove(observer);
}
public void NotificarTodos(string mensagem)
{
foreach (var obs in _observers)
{
obs.Notificar(mensagem);
}
}
}
Criando os Observadores (Observers)🔗
Agora, definimos a interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. dos observadores
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.. Ela só precisa de um método para receber a mensagem:
public interface INotificacaoObserver
{
void Notificar(string mensagem);
}
Cada classe que quer “ficar de olho” no Subject pode implementar essa interface. Por exemplo, podemos criar dois observadores👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.:
1. NotificacaoEmailObserver: envia e-mail quando📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. notificado.
2. NotificacaoLogObserver: grava um log de texto📝 Strings em C#: Manipule Textos como um Mestre dos Caracteres!Aprenda a dominar os segredos das strings em C# com técnicas de manipulação, concatenação, interpolação e boas práticas, impulsionando sua performance..
public class NotificacaoEmailObserver : INotificacaoObserver
{
public void Notificar(string mensagem)
{
Console.WriteLine($"[Email] Notificando usuário: {mensagem}");
// Lógica real de envio de email iria aqui...
}
}
public class NotificacaoLogObserver : INotificacaoObserver
{
public void Notificar(string mensagem)
{
Console.WriteLine($"[Log] Registrando em arquivo: {mensagem}");
// Lógica real de registro em arquivo iria aqui...
}
}
Repare que cada Observer👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. faz seu trabalho de forma independente, sem que o Subject
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. precise saber como exatamente cada notificação será tratada.
Injeção de Dependências no Projeto🔗
Para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! deixar o sistema ainda mais organizado, vamos injetar o Subject e os Observers em quem precisar. Se estivermos usando, por exemplo, o .NET com um container de injeção de dependência
💉 Dependency Injection: Injeção de Dependências com .NET Core!Entenda como a Injeção de Dependências no .NET Core organiza seu código, promovendo modularidade, testes eficientes e fácil manutenção. (como o Microsoft.Extensions.DependencyInjection), poderíamos registrar os serviços assim:
services.AddSingleton<INotificacaoSubject, NotificacaoSubject>();
services.AddTransient<INotificacaoObserver, NotificacaoEmailObserver>();
services.AddTransient<INotificacaoObserver, NotificacaoLogObserver>();
- AddSingleton: o Subject
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. será único na aplicação (faz sentido, pois é a central de notificações).
- AddTransient: cada uso de
INotificacaoObserver
criará uma instância nova (ou poderíamos usar outro tempo de vida🧠 Variáveis em C#: Onde os Dados Ganham Vida (e Nome!)Descubra como as variáveis em C# funcionam, com exemplos do mundo real, boas práticas de nomeação e dicas para otimizar seu código., dependendo da necessidade).
Em algum ponto de inicialização, a gente adiciona essas dependências, e quando precisarmos do Subject👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas., ele já virá com as suas dependências amarradas.
Exemplo de Uso🔗
Imagine que temos um serviço que, em certo momento, precisa avisar a galera (observers👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas.) de algum evento. Ele injeta o
INotificacaoSubject
no construtor🔑 Construtores: Inicialize Objetos como um Arquiteto de OOP!Descubra como os construtores em C# estruturam objetos, garantindo inicialização segura e promovendo boas práticas de desenvolvimento orientado a objetos.:
public class PedidoService
{
private readonly INotificacaoSubject _notificacaoSubject;
public PedidoService(INotificacaoSubject notificacaoSubject)
{
_notificacaoSubject = notificacaoSubject;
}
public void FinalizarPedido()
{
// Outras lógicas: salvar pedido no banco, etc.
Console.WriteLine("Pedido finalizado com sucesso.");
// Agora, notificar todo mundo!
_notificacaoSubject.NotificarTodos("Novo pedido foi finalizado!");
}
}
Quando📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. chamamos
FinalizarPedido()
, a aplicação dispara as notificações para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! todos os Observers
👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. que estiverem cadastrados no
NotificacaoSubject
. Segue um pseudoexemplo de composição (usando injeção manual sem container🐳 Docker 101: Containerize sua API em 15 Minutos!Containerize sua API .NET em 15 minutos com Docker. Este tutorial prático ensina a construir e rodar containers de forma simples e eficiente., só pra ver como seria tudo funcionando junto):
var subject = new NotificacaoSubject();
// Observadores
var emailObserver = new NotificacaoEmailObserver();
var logObserver = new NotificacaoLogObserver();
// Adicionar observadores
subject.AdicionarObserver(emailObserver);
subject.AdicionarObserver(logObserver);
// Serviço que usa o subject
var pedidoService = new PedidoService(subject);
pedidoService.FinalizarPedido();
// Saída esperada:
// Pedido finalizado com sucesso.
// [Email] Notificando usuário: Novo pedido foi finalizado!
// [Log] Registrando em arquivo: Novo pedido foi finalizado!
Conclusão🔗
Usar Observer👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Injeção de Dependências
💉 Dependency Injection: Injeção de Dependências com .NET Core!Entenda como a Injeção de Dependências no .NET Core organiza seu código, promovendo modularidade, testes eficientes e fácil manutenção. tira um peso gigante das costas de quem mantém o código. Você separa claramente quem gera o evento (Subject) de quem reage (Observers), sem criar referências
🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. de classes espalhadas. A DI, por sua vez, permite gerenciar instâncias de forma centralizada e modular.
Essa abordagem pode crescer à vontade: adicione novos observadores👁️ Observer: Notifique Mudanças como um Sistema de Alerta!Aprenda a implementar o padrão Observer para notificações automáticas e comunicação desacoplada, agilizando processos em aplicações diversas. para SMS, push notifications, relatórios... Tudo se encaixa sem bagunçar o código que gera o evento principal. Isso é flexibilidade e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. manutenibilidade na veia.
Dependency Injection: Integrando com o .NET Core🔗
Configuração no Startup
// Program.cs
builder.Services.AddSingleton<ISubject, NotificationSubject>();
builder.Services.AddTransient<IObserver, EmailObserver>();
builder.Services.AddTransient<IObserver, SMSObserver>();
Uso com Injeção de Dependência
public class NotificationService
{
private readonly ISubject _subject;
public NotificationService(ISubject subject, IEnumerable<IObserver> observers)
{
_subject = subject;
foreach (var observer in observers)
{
_subject.Attach(observer);
}
}
public void SendAlert(string message)
{
_subject.Notify(message);
}
}
Código Fonte: Sistema Completo🔗
// NotificationSystem.cs
public interface IObserver { void Update(string message); }
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify(string message);
}
public class NotificationSubject : ISubject
{
private readonly List<IObserver> _observers = new();
public void Attach(IObserver observer) => _observers.Add(observer);
public void Detach(IObserver observer) => _observers.Remove(observer);
public void Notify(string message) => _observers.ForEach(o => o.Update(message));
}
// ObserversConcretos.cs
public class EmailObserver : IObserver
{
public void Update(string message) => Console.WriteLine($"📧 Email: {message}");
}
public class SMSObserver : IObserver
{
public void Update(string message) => Console.WriteLine($"📱 SMS: {message}");
}
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ISubject, NotificationSubject>();
builder.Services.AddTransient<IObserver, EmailObserver>();
builder.Services.AddTransient<IObserver, SMSObserver>();
var app = builder.Build();
app.MapGet("/notify", (ISubject subject, string message) =>
{
subject.Notify(message);
return "Notificações enviadas!";
});
app.Run();
Testando o Sistema🔗
curl "https://localhost:5001/notify?message=Promoção%20Relâmpago!"
2. Saída no Console:
📧 Email: Promoção Relâmpago!
📱 SMS: Promoção Relâmpago!
// Basta implementar IObserver e registrar no DI Container
public class PushNotificationObserver : IObserver
{
public void Update(string message)
=> Console.WriteLine($"📲 Push: {message}");
}
// Registrar no Program.cs:
builder.Services.AddTransient<IObserver, PushNotificationObserver>();
Vantagens da Abordagem🔗
✅ Desacoplamento Total: Subject não conhece implementações concretas dos observers ✅ Extensibilidade Fácil: Adicione novos canais sem modificar o núcleo do sistema ✅ Testabilidade: Mock observers para testes unitários ✅ Gerenciamento Centralizado: Todas notificações partem de um único pontoCenário Real: Sistema de alerta de fraude em transações financeiras, onde🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!Aprenda a usar coleções e LINQ em C# para analisar vendas, filtrar dados e extrair insights estratégicos que otimizem decisões e impulsionem seu negócio. múltiplos sistemas precisam ser notificados simultaneamente.
Desafios Comuns e Soluções🔗
Desafio | Solução |
---|---|
Ordem de notificação | Usar IOrderedEnumerable no DI |
Vazamento de memória | Implementar IDisposable |
Exceções em observers | Usar try/catch por observer |
Performance com muitos observers | Usar paralelismo controlado |
public void Notify(string message)
{
Parallel.ForEach(_observers, observer =>
{
try
{
observer.Update(message);
}
catch (Exception ex)
{
// Log error, don't break all notifications
_logger.LogError(ex, "Erro no observer");
}
});
}
Conclusão e Próximos Passos🔗
Você criou um sistema de notificações escalável📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. usando padrões profissionais! Para evoluir:
// Desafio: Implementar observer com filtro
public class PriorityEmailObserver : IObserver
{
public void Update(string message)
{
if (message.StartsWith("[URGENTE]"))
{
// Lógica especial para emails prioritários
}
}
Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.
Referências🔗
- .NET Documentation: learn.microsoft.com/pt-br/dotnet/
- Awesome .NET: github.com/quozd/awesome-dotnet
- C# Language Specification: learn.microsoft.com/pt-br/dotnet/csharp/language-reference/language-specification/
- GitHub: Microsoft/.NET: github.com/dotnet
- Microsoft Learn: C# e .NET: learn.microsoft.com/pt-br/dotnet/csharp/