Grupy google umożliwiają prowadzenie rozległych dyskusji na konkretne tematy. Zakładając grupę dyskusyjną mamy możliwość wysyłania do niej wiadomości. Każdy zainteresowany tematem może sobie zasubskrybować grupę i otrzymywać wszystkie wysyłane na nią wiadomości. Jeśli temat przestanie go interesować, może anulować subskrypcję. Osoba wysyłająca wiadomości nie musi przejmować się tym, kto obecnie subskrybuje jej wiadomości - są one wysyłane na adres grupy.
Zastosowanie:
Wzorzec obserwatora stosujemy, gdy jeden obiekt zależny jest od innego i zmiana stanu jednego obiektu powinna powodować zmianę innych obiektów. Często używając wzorca obserwatora nie mamy wiedzy na temat tego, jakie obiekty powiadamiamy.
Zasada działania:
Tradycyjne podejście do wzorca obserwatora zakłada stworzenie dwóch klas abstrakcyjnych : podmiotu i obserwatora. Obserwator zawiera referencję do podmiotu i może go aktualizować. Podmiot może rejestrować nowych obserwatorów (zawiera kolekcję obserwatorów), a także usuwać już zarejestrowanych. Może także notyfikować wszystkich o zmianie stanu. Ponadto może się też zdarzyć, że obserwatorzy będą chcieli modyfikować źródło notyfikacji, co należy odpowiednio zaimplementować.
Przykład implementacyjny:
public interface IAbstractObserver { void Update(int number); } public class Counter : IAbstractObserver { public Counter(IAbstractSubject sub) { sub.Subscribe(this); } public static int Count { get; set; } public void Update(int n) { Count++; } } public class Printer : IAbstractObserver { public Printer(IAbstractSubject sub) { sub.Subscribe(this); } public void Update(int n) { Console.WriteLine(n); } }
public interface IAbstractSubject { void Subscribe(IAbstractObserver observer); void Unsubscribe(IAbstractObserver observer); void Notify(); } public class RandomNumbers : IAbstractSubject { private List<IAbstractObserver> _observers = new List<IAbstractObserver>(); private int _randomNumber; public int RandomNumber { get { return _randomNumber; } set { _randomNumber = value; Notify(); } } public void Subscribe(IAbstractObserver observer) { _observers.Add(observer); } public void Unsubscribe(IAbstractObserver observer) { _observers.Remove(observer); } public void Notify() { foreach (IAbstractObserver abstractObserver in _observers) { abstractObserver.Update(_randomNumber); } } }
class Program { static void Main(string[] args) { RandomNumbers rn = new RandomNumbers(); Printer printer = new Printer(rn); Counter counter = new Counter(rn); Random r = new Random(); for (int i = 0; i < 10; i++) { int number = r.Next(0, 10); rn.RandomNumber = number; Thread.Sleep(number*100); } Console.WriteLine(Counter.Count); Console.Read(); } }
Powyższa implementacja jest podejściem klasycznym. Platforma .NET Framework udostępnia zdarzenia i delegatów, za pomocą których można uzyskać podobny efekt.
Brak komentarzy:
Prześlij komentarz