1. Observer Pattern là gì?
Observer (Người quan sát) Pattern là một trong những Pattern thuộc nhóm hành vi (Behavior Pattern). Nó định nghĩa mối quan hệ phụ thuộc một – nhiều giữa các đối tượng để khi mà một đối tượng có sự thay đổi trạng thái, tất các thành phần phụ thuộc của nó sẽ được thông báo và cập nhật một cách tự động.
Observer có thể đăng ký với hệ thống. Khi hệ thống có sự thay đổi, hệ thống sẽ thông báo cho Observer biết. Khi không cần nữa, mẫu Observer sẽ được gỡ khỏi hệ thống.

- Hình 1-8, cho phép observer thứ 1 đăng ký với hệ thống.
- Hình 1-9, cho phép observer thứ 2 đăng ký với hệ thống.
- Hiện tại hệ thống đang liên lạc với 2 observer: Observer 1 và Observer 2. Khi hệ thống phát sinh một sự kiện cụ thể nào đó, nó sẽ thông báo (notification) với cả 2 observer như hình số 1-10.
Observer Pattern còn gọi là Dependents, Publish/Subcribe hoặc Source/Listener.
2. Cấu trúc

3. Sử dụng Obsrever Pattern khi nào?
- Thường được sử dụng trong mối quan hệ 1-n giữa các object với nhau. Trong đó một đối tượng thay đổi và muốn thông báo cho tất cả các object liên quan biết về sự thay đổi đó.
- Khi thay đổi một đối tượng, yêu cầu thay đổi đối tượng khác và chúng ta không biết có bao nhiêu đối tượng cần thay đổi, những đối tượng này là ai.
- Sử dụng trong ứng dụng broadcast-type communication.
- Sử dụng để quản lý sự kiện (Event management).
- Sử dụng trong mẫu mô hình MVC (Model View Controller Pattern) : trong MVC, mẫu này được sử dụng để tách Model khỏi View. View đại diện cho Observer và Model là đối tượng Observable.
4. Cách triển khai và code ví dụ
using System;
using System.Collections.Generic;
using System.Threading;
namespace DesignPatternsObserver
{
public interface IObserver
{
// Hàm nhận update từ Subject
void Update(ISubject subject);
}
public interface ISubject
{
// Thêm một observer
void Attach(IObserver observer);
// Gỡ bỏ một observer
void Detach(IObserver observer);
// Gửi thông báo tới tất cả các observer
void Notify();
}
// Class bao gồm các trạng thái của observer
// và gửi thông báo tới các observer khi trạng
// thái thay đổi
public class Subject : ISubject
{
// Variable lưu trạng thái của các observer
public int State { get; set; } = -0;
// List lưu danh sách các observer được đăng ký
private List<IObserver> _observers = new List<IObserver>();
// Thêm một observer
public void Attach(IObserver observer)
{
Console.WriteLine("Subject: Attached an observer.");
this._observers.Add(observer);
}
// Gỡ một observer
public void Detach(IObserver observer)
{
this._observers.Remove(observer);
Console.WriteLine("Subject: Detached an observer.");
}
// Gửi thông báo tới các observer được đăng ký
public void Notify()
{
Console.WriteLine("Subject: Notifying observers...");
foreach (var observer in _observers)
{
observer.Update(this);
}
}
// Xử lý logic và gửi thông báo tới các observer được đăng ký
public void SomeBusinessLogic()
{
Console.WriteLine("\nSubject: I'm doing something important.");
this.State = new Random().Next(0, 10);
Thread.Sleep(15);
Console.WriteLine("Subject: My state has just changed to: " + this.State);
this.Notify();
}
}
class ConcreteObserverA : IObserver
{
public void Update(ISubject subject)
{
// ConcreteObserverA chỉ react khi State < 3
if ((subject as Subject).State < 3)
{
Console.WriteLine("ConcreteObserverA: Reacted to the event.");
}
}
}
class ConcreteObserverB : IObserver
{
public void Update(ISubject subject)
{
// ConcreteObserverB chỉ phản ứng khi State = 0 hoặc State >= 2
if ((subject as Subject).State == 0 || (subject as Subject).State >= 2)
{
Console.WriteLine("ConcreteObserverB: Reacted to the event.");
}
}
}
class Program
{
static void Main(string[] args)
{
// The client code.
var subject = new Subject();
var observerA = new ConcreteObserverA();
subject.Attach(observerA);
var observerB = new ConcreteObserverB();
subject.Attach(observerB);
subject.SomeBusinessLogic();
subject.SomeBusinessLogic();
subject.Detach(observerB);
subject.SomeBusinessLogic();
Console.ReadKey();
}
}
}