Design patterns 对象事件,它们是如何实现的

Design patterns 对象事件,它们是如何实现的,design-patterns,events,observer-pattern,Design Patterns,Events,Observer Pattern,这些活动真是太棒了,没有它们我不知道该怎么办,但它们对我来说是个谜 我说的是事件,从某种意义上说,如果某个属性或值发生特殊事件,就会调用函数 我对它们的实际工作原理只有一点模糊的概念。我知道这是一种观察者模式,但我不知道它是如何工作和/或如何实现的 有人能给我解释一下吗?谷歌带来的简单快捷 及 谷歌带来的简单快捷 及 事实上,事件在高层次上非常简单 首先,一个对象定义了一个其他对象可以订阅的事件。当一个对象注册一个事件时,该对象存储一个函数引用(或委托),该函数引用(或委托)将在事件发生时被

这些活动真是太棒了,没有它们我不知道该怎么办,但它们对我来说是个谜

我说的是事件,从某种意义上说,如果某个属性或值发生特殊事件,就会调用函数

我对它们的实际工作原理只有一点模糊的概念。我知道这是一种观察者模式,但我不知道它是如何工作和/或如何实现的


有人能给我解释一下吗?

谷歌带来的简单快捷


谷歌带来的简单快捷


事实上,事件在高层次上非常简单

首先,一个对象定义了一个其他对象可以订阅的事件。当一个对象注册一个事件时,该对象存储一个函数引用(或委托),该函数引用(或委托)将在事件发生时被调用

接下来,感兴趣的对象通过向可观察对象传递函数引用来订阅事件(函数必须与可观察类提供的签名匹配)

当事件发生时,可观察类调用适当的方法

下面是一个简单的例子(用C#):

然后在另一个想要订阅已更改事件的类中:

public class Observer
{
    ObservableObject _obj = new ObservableObject();

    public Observer()
    {
        // Pass the function reference to objChangedHandler to the
        // Observable Object.
        _obj.Changed += objChangedHandler;
    }

    public void objChangedHandler(object sender, EventArgs e)
    {
        // Handle the event here
    }
}

在高层次上,事件实际上非常简单

首先,一个对象定义了一个其他对象可以订阅的事件。当一个对象注册一个事件时,该对象存储一个函数引用(或委托),该函数引用(或委托)将在事件发生时被调用

接下来,感兴趣的对象通过向可观察对象传递函数引用来订阅事件(函数必须与可观察类提供的签名匹配)

当事件发生时,可观察类调用适当的方法

下面是一个简单的例子(用C#):

然后在另一个想要订阅已更改事件的类中:

public class Observer
{
    ObservableObject _obj = new ObservableObject();

    public Observer()
    {
        // Pass the function reference to objChangedHandler to the
        // Observable Object.
        _obj.Changed += objChangedHandler;
    }

    public void objChangedHandler(object sender, EventArgs e)
    {
        // Handle the event here
    }
}
您需要为您的观察者提供一个接口(不一定是接口关键字意义上的接口,例如java/c),您需要知道在需要时调用哪个方法 通知他们。观察员登记他们的兴趣,你将他们添加到列表中

每次你有事情要通知的时候,你都会浏览观察者名单,然后 对它们中的每一个调用一个方法。当有人不想再被通知时,只需将他们从你的观察者列表中删除即可

下面是一个c#示例,没有使用c#中的内置“事件”或委托:

使用系统;
使用System.Collections.Generic;
名称空间观察者测试
{
接口转换器
{
作废更新(库存);
}
抽象类股票
{
私有字符串_符号;
私人双价;
私人名单_investors=新名单();
//建造师
公开股票(字符串符号,双倍价格)
{
这个._symbol=symbol;
这个价格=价格;
}
公共无效附件(投资者)
{
_投资者。添加(投资者);
}
公众投资者(投资者)
{
_投资者。移除(投资者);
}
公告
{
foreach(投资者中的投资者)
{
投资者。更新(本);
}
控制台。写线(“”);
}
公共双价
{
获取{return\u price;}
设置
{
如果(_price!=值)
{
_价格=价值;
通知();
}
}
}
公共字符串符号
{
获取{return\u symbol;}
}
}
类别:股票
{
公共IBM(字符串符号,双倍价格)
:基准(符号、价格)
{
}
}
类别投资者:投资者
{
私有字符串\u名称;
//建造师
公共投资者(字符串名称)
{
这个。_name=name;
}
公开作废更新(库存)
{
WriteLine(“通知了{0}的{1}”+
“更改为{2:C}”,即名称、股票.符号、股票.价格);
}
}
类MainApp
{
静态void Main()
{
IBM=新IBM(“IBM”,120.00);
ibm.Attach(新投资者(“Sorros”);
ibm.Attach(新投资者(“伯克希尔”);
ibm.Price=120.10;
ibm.Price=121.00;
ibm.Price=120.50;
ibm.Price=120.75;
Console.ReadKey();
}
}
}
您需要为您的观察者提供一个接口(不一定是接口关键字意义上的接口,例如java/c),您需要知道在需要时调用哪个方法 通知他们。观察员登记他们的兴趣,你将他们添加到列表中

每次你有事情要通知的时候,你都会浏览观察者名单,然后 对它们中的每一个调用一个方法。当有人不想再被通知时,只需将他们从你的观察者列表中删除即可

下面是一个c#示例,没有使用c#中的内置“事件”或委托:

使用系统;
使用System.Collections.Generic;
名称空间观察者测试
{
接口转换器
{
作废更新(库存);
}
抽象类股票
{
私有字符串_符号;
私人双价;
私人名单_investors=新名单();
//建造师
公开股票(字符串符号,双倍价格)
{
这个._symbol=symbol;
这个价格=价格;
}
公共无效附件(投资者)
{
_投资者。添加(投资者);
}
公众投资者(投资者)
{
_投资者。移除(投资者);
}
公告
{
foreach(投资者中的投资者)
{
投资者。更新(本);
}
控制台。写线(“”);
}
公共双价
{
获取{return\u price;}
设置
{
如果(_price!=值)
{
_价格=价值;
通知();
}
}
}
公共字符串符号
{
获取{return\u symbol;}
}
}
类别:股票
{
公共IBM(字符串符号,双倍价格)
:基准(符号、价格)
{
}
}
类别投资者
using System;
using System.Collections.Generic;
namespace ObserverTest
{

interface IInvestor
{
    void Update(Stock stock);
}


abstract class Stock
{
    private string _symbol;
    private double _price;
    private List<IInvestor> _investors = new List<IInvestor>();
    // Constructor
    public Stock(string symbol, double price)
    {
        this._symbol = symbol;
        this._price = price;
    }
    public void Attach(IInvestor investor)
    {
        _investors.Add(investor);
    }
    public void Detach(IInvestor investor)
    {
        _investors.Remove(investor);
    }
    public void Notify()
    {
        foreach (IInvestor investor in _investors)
        {
            investor.Update(this);
        }
        Console.WriteLine("");
    }
    public double Price
    {
        get { return _price; }
        set
        {
            if (_price != value)
            {
                _price = value;
                Notify();
            }
        }
    }
    public string Symbol
    {
        get { return _symbol; }
    }
}
class IBM : Stock
{
    public IBM(string symbol, double price)
    : base(symbol, price)
    {
    }
}



class Investor : IInvestor
{
    private string _name;
    // Constructor
    public Investor(string name)
    {
        this._name = name;
    }
    public void Update(Stock stock)
    {
        Console.WriteLine("Notified {0} of {1}'s " +
        "change to {2:C}", _name, stock.Symbol, stock.Price);
    }
}
class MainApp
{
    static void Main()
    {

        IBM ibm = new IBM("IBM", 120.00);
        ibm.Attach(new Investor("Sorros"));
        ibm.Attach(new Investor("Berkshire"));
        ibm.Price = 120.10;
        ibm.Price = 121.00;
        ibm.Price = 120.50;
        ibm.Price = 120.75;

        Console.ReadKey();
    }
}
}