Observer Pattern, Delegate and Event

When we learn the Observer Pattern, we will see the Figure like this:

It come from the << Head.First.Design.Patterns>>. Let us to learn this pattern together....

Observer is a abstract class or interface, it define a series of methods. these methods can be executed when the Subject have a notify to happen. Now, i give some code to analyse it:

namespace  ObserverPattern2
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            Observer1 o1 
=   new  Observer1();
            Observer2 o2 
=   new  Observer2();

            Subject subject 
=   new  Subject();
            subject.RegisterObserver(o1);
            subject.RegisterObserver(o2);

            subject.Notify(
" billok " );
            subject.Notify(
" billchen " );
            subject.RemoveObserver(o2);
            subject.Notify(
" cjb " );

            Console.ReadLine();
        }
    }

    
public   abstract   class  Observer
    {
        
public   abstract   void  Update( string  userName);
    }

    
public   class  Observer1 : Observer
    {
        
public   override   void  Update( string  userName)
        {
            Console.WriteLine(
" Update Observer1  "   +  userName);
        }
    }

    
public   class  Observer2 : Observer
    {
        
public   override   void  Update( string  userName)
        {
            Console.WriteLine(
" Update Observer2  "   +  userName);
        }
    }

    
public   interface  ISubject
    {
        
void  RegisterObserver(Observer observer); // register an Observer
         void  RemoveObserver(Observer observer); // remove an Observer
         void  Notify( string  userName); // notify observers when the state is changed
    }

    
public   class  Subject : ISubject
    {
        
private  List < Observer >  observers;

        
public  Subject()
        {
            observers 
=   new  List < Observer > ();
        }

        
public   void  RegisterObserver(Observer observer)
        {
            
if  ( ! observers.Contains(observer))
                observers.Add(observer);
        }

        
public   void  RemoveObserver(Observer observer)
        {
            
int  i  =  observers.IndexOf(observer);
            
if  (i  >=   0 )
                observers.Remove(observer);
        }

        
public   void  Notify( string  userName)
        {
            
foreach  (Observer observer  in  observers)
            {
                observer.Update(userName);
            }
        }
    }
}

Observer1 and Observer2 are the implement of abstract Observer. They really finish the Update(string userName) method. This method will be executed when Observer is notified.

How to notify these Observer? It is Subject's duty. ISubject define three methods(RegisterObserver, RemoveObserver, Notify). RegisterObserver is used to register a new Observer, this observer will be notified when subject's Notify method is executed.
RemoveObserver is used to remove existent Observer, then it will be not notified.
Notify is used to tigger an action, this action will be notify all of Observers of the storage of the Subject.

Now, Subject is a implementing class of the ISubject interface.

How to use this Observer Pattern to finish our job? First, we can create a Subject object, and create some Observer's implements. Next, you add the objects to the Subject object by RegisterObserver method. Finally, we execute the Notify method, and all of the Observer will be notified and their Update method will be executed.

Maybe you can take note of my codes is differ from the Figure. In the Figure, ConcreteObserver class have a reference of the ISubject. we can come true it. I think it's duty is simply register itseft to the subject. Let us to add a Isubject reference to the Observer, like this:

     public   abstract   class  Observer
    {
        
private  ISubject iSubject;

        
private  Observer() { }
        
public  Observer(ISubject iSubject)
        {
            
this .iSubject  =  iSubject;
            
this .iSubject.RegisterObserver( this ); // register itseft
        }

        
public   abstract   void  Update( string  userName);
    }

when we new a Observer object, reference of ISubject is added to the new object. Now, we may modify the using of the RegisterObserve. Please look this:

Subject subject  =   new  Subject();
Observer1 o1 
=   new  Observer1(subject);
Observer2 o2 
=   new  Observer2(subject);
subject.Notify(
" billok " );

Okay, i give another version:

ContractedBlock.gif ExpandedBlockStart.gif another version
namespace ObserverPattern2_2
{
    
class Program
    {
        
static void Main(string[] args)
        {
            Subject subject 
= new Subject();
            Observer1 o1 
= new Observer1(subject);
            Observer2 o2 
= new Observer2(subject);

            subject.Notify(
"billok");
            subject.Notify(
"billchen");
            subject.RemoveObserver(o2);
            subject.Notify(
"cjb");

            Console.ReadLine();
        }
    }

    
public abstract class Observer
    {
        
private ISubject iSubject;

        
private Observer() { }
        
public Observer(ISubject iSubject)
        {
            
this.iSubject = iSubject;
            
this.iSubject.RegisterObserver(this);//register itseft
        }

        
public abstract void Update(string userName);
    }

    
public class Observer1 : Observer
    {
        
public Observer1(ISubject iSubject) : base(iSubject) { }

        
public override void Update(string userName)
        {
            Console.WriteLine(
"Update Observer1 " + userName);
        }
    }

    
public class Observer2 : Observer
    {
        
public Observer2(ISubject iSubject) : base(iSubject) { }

        
public override void Update(string userName)
        {
            Console.WriteLine(
"Update Observer2 " + userName);
        }
    }

    
public interface ISubject
    {
        
void RegisterObserver(Observer observer);//register an Observer
        void RemoveObserver(Observer observer);//remove an Observer
        void Notify(string userName);//notify observers when the state is changed
    }

    
public class Subject : ISubject
    {
        
private List<Observer> observers;

        
public Subject()
        {
            observers 
= new List<Observer>();
        }

        
public void RegisterObserver(Observer observer)
        {
            
if (!observers.Contains(observer))
                observers.Add(observer);
        }

        
public void RemoveObserver(Observer observer)
        {
            
int i = observers.IndexOf(observer);
            
if (i >= 0)
                observers.Remove(observer);
        }

        
public void Notify(string userName)
        {
            
foreach (Observer observer in observers)
            {
                observer.Update(userName);
            }
        }
    }
}


      Okay, Now! Let us take attention to the implement of Observer Pattern in C#.

We should use the Delegate and Event to implement the Observer Pattern in the .NET Framework. I give the new edition for .net like it:

namespace  ObserverPattern3
{
    
class  Program
    {
        
static   void  Main( string [] args)
        {
            Trigger trigger 
=   new  Trigger();
            trigger.Changed 
+=   new  Trigger.ChangedEventHandler(trigger_Changed);
            trigger.Changed 
+=   delegate ( object  sender, ChangedEventArgs e)
            {
                Console.WriteLine(
" delegate Observer:  " + e.UserName);
            };
            trigger.Changed 
+=  Observer1;
            trigger.Changed 
+=  Observer2;

            trigger.Update(
" billok " );
            trigger.Changed 
-=  Observer2;
            trigger.Update(
" cjb " );

            Console.ReadLine();
        }

        
static   void  trigger_Changed( object  sender, ChangedEventArgs e)
        {
            Console.WriteLine(
" custom Observer:  "   +  e.UserName);
        }

        
public   static   void  Observer1(Object sender, ChangedEventArgs e)
        {
            Console.WriteLine(
" Observer1:  "   +  e.UserName);
        }

        
public   static   void  Observer2(Object sender, ChangedEventArgs e)
        {
            Console.WriteLine(
" Observer2:  "   +  e.UserName);
        }
    }


    
public   class  ChangedEventArgs : EventArgs
    {
        
public   readonly   string  UserName;

        
public  ChangedEventArgs( string  userName)
        {
            
this .UserName  =  userName;
        }
    }

    
public   class  Trigger
    {
       
// declare a delegate variable.
        
public   delegate   void  ChangedEventHandler(Object sender, ChangedEventArgs e);
         public   event  ChangedEventHandler Changed; // declare a event.

        
protected   virtual   void  OnChanged(ChangedEventArgs e)
        {
            
if  (Changed  !=   null )
            {
                Changed(
this , e);
            }
        }

        
public   void  Update( string  userName)
        {
            ChangedEventArgs e 
=   new  ChangedEventArgs(userName);
            OnChanged(e);
        }
    }
}

You can see i define a Delegate variable and Event variable in the Trigger classs.
Please notice how to define the event frame.
attention:

  • The name of Delegate type must end by EventHandler.
  • Definition of Delegate must have "void" return value, and it have two parameters, one is Object type, One is EventArgs type or implement of the EventArgs.
  • The name of Event is remove the "EventHandler" from the name of Delegate.
  • The name of Implement of the EventArgs should end by EventArgs.

How to register and remove the observer? we can use "+=" and "-=" to do it. please look the source code.

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/BillChen/archive/2008/10/23/1318000.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值