惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
K
Kaspersky official blog
A
Arctic Wolf
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
N
News | PayPal Newsroom
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
W
WeLiveSecurity
Know Your Adversary
Know Your Adversary
博客园 - Franky
T
Tenable Blog
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Help Net Security
Help Net Security
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
J
Java Code Geeks
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
NISL@THU
NISL@THU
O
OpenAI News
The Cloudflare Blog
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
V
V2EX
罗磊的独立博客
美团技术团队
博客园 - 三生石上(FineUI控件)
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏

博客园 - 网际飞狐

异步服务框架 如何在TFS中用命令行提交更新 CollabNet Subversion 输出自定义日期格式 - 网际飞狐 - 博客园 你正确关闭WCF链接了吗? 通过OperationContext添加消息头信息 PHP在II7安装指南 [Google App Engine] Hello, world! 在IIS7中配置使用Python 2008年12月小记(NewSequentialID(),ADO.NET Data Service,Visual Studio Tips,安装Django,JQuery智能感知) [OpenAPI] html标签分析 System.Web.Routing 使用基础 Notes for 2008-11(GetRange, backup,file hash, PostRequest, QueryString) JS通过服务代理调用跨域服务 对硬编码WCF服务的封装(提供服务和客户端调用的封装,调用样例....) How to view the W3WP process by c#? 项目框架概要 2008年10月小记(SQL删除重复记录,生成表结构,字符串特性,statistics io) WinDbg使用摘要
Observer Pattern, Delegate and Event
网际飞狐 · 2008-10-23 · via 博客园 - 网际飞狐

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:

another version

      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.