O Uso de Callback Passando por Parâmetro em .NET: Uma Abordagem Prática para Comunicação entre Componentes
Quando estamos desenvolvendo sistemas complexos, é comum nos depararmos com a necessidade de diferentes componentes ou classes se comunicarem de forma eficiente e desacoplada. Uma das maneiras mais poderosas de se fazer isso em .NET é utilizando callbacks, ou seja, passando métodos como parâmetros entre diferentes classes para que um componente possa notificar outro sobre eventos ou mudanças de estado.
Neste artigo, vamos explorar como utilizar callbacks em C#, passando métodos como parâmetros para gerenciar a comunicação entre classes de forma simples e eficiente.
O que é um Callback?
Um callback é uma técnica onde você passa um método (ou função) como argumento para outro método. Esse método passado é então chamado dentro do método que o recebeu, geralmente como resposta a um evento ou operação assíncrona. Em outras palavras, o método de callback é invocado quando uma ação específica ocorre, permitindo que você defina o comportamento do sistema em tempo de execução.
Em C#, os callbacks geralmente são implementados utilizando delegates ou expressões lambda, tornando a integração de métodos em sistemas mais flexível e dinâmica.
Exemplo Prático: Monitoramento de Temperatura com Callback
Vamos considerar um exemplo de monitoramento de temperatura. Imaginemos que você tenha uma classe responsável por medir a temperatura e outra classe que exibe o valor da temperatura a cada medição. Podemos usar callbacks para notificar a classe que exibe a temperatura sobre as alterações feitas na classe de medição.
1. A Classe de Medição de Temperatura
Na classe Weather, vamos simular a medição de temperatura. Ela irá gerar uma temperatura aleatória e passá-la para a classe Program através de um callback.
namespace TestParameterEvent
{
internal class Weather
{
private readonly Random _random = new Random();
public void MeasureTemperature(Action<int> callback, int temperaturaAtual)
{
while (true)
{
// Aguarda 1 minuto (simulado como 10 segundos para testes)
Thread.Sleep(600000);
// Gera uma variação aleatória de -2 a 2 graus
int variacao = _random.Next(-2, 3); // Pode ser -2, -1, 0, 1, ou 2
// Calcula a nova temperatura com base na variação
int novaTemperatura = temperaturaAtual + variacao;
// Garante que a temperatura não caia abaixo de 0°C (para simulação realista)
novaTemperatura = Math.Max(novaTemperatura, 0);
// Dispara o callback passando a nova temperatura
callback(novaTemperatura);
}
}
}
}
2. A Classe Principal (Program)
Na classe Program, o método Main inicia o monitoramento, passando o método ShowTemperature como callback para a classe Weather. A classe Program será responsável por exibir a temperatura atualizada sempre que a medição for realizada.
using System;
using TestParameterEvent;
public class Program
{
private static int temperature = 24; // Temperatura inicial
public static void Main(string[] args)
{
Console.WriteLine("Iniciando monitoramento de temperatura...");
ShowTemperature(temperature); // Exibe a temperatura inicial
// Cria uma instância de Weather
Weather weather = new Weather();
// Passa o método ShowTemperature como callback para Weather.MeasureTemperature
weather.MeasureTemperature(ShowTemperature, temperature);
}
public static void ShowTemperature(int novaTemperatura)
{
// Captura o horário atual para imprimir no formato hh:mm:ss
string hora = DateTime.Now.ToString("HH:mm:ss");
// Mensagem de variação de temperatura
if (novaTemperatura > temperature)
{
Console.WriteLine($"{hora} - A temperatura subiu de {temperature}°C para {novaTemperatura}°C.");
}
else if (novaTemperatura < temperature)
{
Console.WriteLine($"{hora} - A temperatura caiu de {temperature}°C para {novaTemperatura}°C.");
}
else
{
Console.WriteLine($"{hora} - A temperatura permaneceu estável em {temperature}°C.");
}
// Atualiza a temperatura atual
UpdateTemperature(novaTemperatura);
}
public static void UpdateTemperature(int novaTemperatura)
{
temperature = novaTemperatura;
}
}
Como Funciona?
Classe Program (Main): Inicia o processo, definindo a temperatura inicial em 24°C e passando o método ShowTemperature como callback para o método MeasureTemperature da classe Weather. Quando a temperatura é alterada, o método ShowTemperature é chamado para mostrar a alteração no console.
Classe Weather: Simula a medição da temperatura, alterando-a aleatoriamente entre -2°C e +2°C a cada 10 minutos. Depois de calcular a nova temperatura, ela chama o método callback, que é o método ShowTemperature de Program.
Callback ShowTemperature: O método ShowTemperature recebe a nova temperatura e imprime a mudança no console, incluindo a hora da medição. Ele também atualiza a variável temperature para refletir a nova temperatura.
Resultado
Ao executar o programa, a saída no console se parecerá com isso:
Iniciando monitoramento de temperatura...
10:25:31 - A temperatura permaneceu estável em 24°C.
10:35:31 - A temperatura permaneceu estável em 24°C.
10:45:31 - A temperatura caiu de 24°C para 22°C.
Vantagens do Uso de Callback em .NET
O uso de callbacks em .NET oferece várias vantagens, como:
Desacoplamento: As classes ficam mais independentes. No exemplo, a classe Weather não precisa saber nada sobre como a classe Program exibe a temperatura, o que facilita a manutenção e evolução do sistema.
Flexibilidade: Você pode passar diferentes métodos como callback para comportamentos diferentes sem alterar a lógica interna das classes. Isso torna o sistema mais flexível e adaptável a novas necessidades.
Facilidade de Extensão: Novos comportamentos podem ser facilmente adicionados. Se precisar de mais ações a serem tomadas quando a temperatura for medida, basta criar novos métodos de callback.
Conclusão
O uso de callback passando por parâmetro é uma técnica poderosa para criar sistemas desacoplados e flexíveis. No exemplo que discutimos, vimos como ela pode ser aplicada de maneira simples em um sistema de monitoramento de temperatura. Com essa abordagem, podemos facilmente adicionar novos comportamentos sem impactar diretamente o fluxo principal do programa, o que é essencial para o desenvolvimento de sistemas robustos e escaláveis.