2013年11月26日 星期二

Design Pattern : Observer

Design Pattern : Observer

Definition :
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.






Observer :
觀察者,必須有讓Subject可以Notify的方法。
Subject:可以訂閱取消訂閱Observer,並有Notify所有訂閱的Observer的方法。

底下的範例,是將車子實作IObserver後, 統一由Subject對所有車子做推播(Notify)以更新行車電腦。

1.  IObserver
public interface IObserver
{
  
void Update();
}


2.  車子類別:除了實作ICar,也實作IObserver作的Update方法。

public class Enzo : ICar, IObserver
{
   
// 省略實作ICar的程式瑪
   
public void Update()
    {
      
Console.WriteLine("{0} 已更新行車電腦!", this.Name);
    }
}

public class EF50 : ICar, IObserver
{
   
// 省略實作ICar的程式瑪
   
public void Update()
    {
      
Console.WriteLine("{0} 已更新行車超級電腦!", this.Name);
    }
}

3.  ISubject

public interface ISubject
{
   
List<IObserver> Observers { get; set; }
   
void Attach(IObserver observer);
   
void Detach(IObserver observer);
   
void Notify();
}

4.  Subject

public class Subject : ISubjec
{
   
public List<IObserver> Observers { get; set; }
   
public Subject()
    {
      
this.Observers = new List<IObserver>();
    }
   
public void Attach(IObserver observer)
    {
      
if (!this.Observers.Contains(observer))
         
this.Observers.Add(observer);
    }
   
public void Detach(IObserver observer)
    {
      
if (this.Observers.Contains(observer))
         
this.Observers.Remove(observer);
    }

   
public void Notify()
    {
       
foreach(IObserver observer in this.Observers){
          observer.Update();
        }
    }
}

5.  主程式:
ICar enzo = new Enzo();
ICar f50 = new F50();
ISubject carSubject = new Subject();

carSubject.Attach(enzo
as IObserver);
carSubject.Attach(f50
as IObserver);
carSubject.Notify();


結果:
Enzo
已更新行車電腦!
F50
已更新行車超級電腦!


6.  另外也有Coder利用delegate+event的方法在run-time才加入Update的方法,可以參考Observer Design Pattern (Delegates/Events)

沒有留言:

張貼留言