Observable
O situație des întâlnită în programare este atunci când dorim să urmărim progresul unei computații sau să emitem evenimente după finalizarea acesteia, care să declanșeze alte acțiuni.
Un exemplu poate fi atunci când dorim să preluăm în mod asincron date de pe un server și să le afișăm într-o interfață web. Mai întâi, inițializăm apelul asincron către server, pentru a nu bloca firul de execuție care randează pagina, iar atunci când datele sosesc, actualizăm interfața.
În această situație, dorim să avem una sau mai multe componente cu rol de observator (observer) și una cu rol de observabil (observable).
Exemplul de mai jos este unul simplu pentru un observabil. O clasă concretă poate să-l moștenească, iar alte componente pot să-și aboneze acțiunile la acesta.
// Clasa este abstracta si trebuie mostenita, de asemena putem pune si
// un la parametru de genericitate pentru a sti ce fel de date proceseaza observabilul
public abstract class Observable<TInput>
{
// Tinem o lista cu actiunile ce trebuie sa se execute la o computatie,
// tipul Action<TInput> este o functie care ia un parametru de tip TInput si nu returneaza nimic
private readonly List<Action<TInput>> _actions = [];
// Observatori pot sa-si inregistreze apeluri (callbacks) la metode proprii pentru a lua actiuni in cazul unei actualizari
public void Subscribe(Action<TInput> onAction)
{
_actions.Add(onAction);
}
// Aceasta e metoda ce trebuie apelata atunci cand actualizam date in clasa care mosteneste
// astfel incat sa fie apelate a
public void OnAction(TInput input)
{
foreach (var action in _actions)
{
action(input);
}
}
}