简体   繁体   English

用事件实现观察者模式

[英]Implementing observer pattern with events

I am working on a Silverlight application where I made excessive use of the observer pattern. 我正在开发一个Silverlight应用程序,我过度使用了观察者模式。 In my implementation I have created two interfaces IObservable<T> and IObserver<T> . 在我的实现中,我创建了两个接口IObservable<T>IObserver<T> The former contains methods to attach and detach observers to the observable. 前者包含将观察者附加到观察者的方法。 The latter has a method Notify(IObservable<T> observable, ...) that is called by the observable passing itself as parameter via observer.Notify(this, ...) when the observable has changed its state. 后者有一个方法Notify(IObservable<T> observable, ...) ,当observable改变了它的状态时,observable通过observer.Notify(this, ...)传递自身作为参数。

Now I have stumbled upon "events" and for me it seems pretty much as if this were an implementation of the observer pattern, just with delegates instead of the aforementioned Notify -method. 现在我偶然发现了“事件”,对我来说,这似乎就像是观察者模式的一个实现,只是代表而不是前面提到的Notify -method。 Is that right? 那正确吗?

I do not know much about delegates and do not want to spend hours on rewriting my code just to end up with code that does the same thing as it already does. 我不太了解代表,并且不想花费数小时来重写我的代码,只是为了最终得到与它已经做同样事情的代码。 On the other hand events might be superior to the interface-based observer pattern. 另一方面,事件可能优于基于接口的观察者模式。 Am I missing something? 我错过了什么吗?

Events are an implementation of the observer pattern . 事件是观察者模式的实现。

An event is implemented as a list of methods to be called when the vent is raised. 事件被实现为引发通风口时要调用的方法列表。

Delegates are method references: in contrast to Java, C# offers a way to refer to a method. 代理是方法引用:与Java相比,C#提供了一种引用方法的方法。

It's not a priori better to use events than implement the observer pattern oneself. 使用事件比自己实现观察者模式更好。 But events offer a quite generic way to do it, and are in many cases highly optimized for the task, thus give a more efficient and convenient way organize this. 但事件提供了一种非常通用的方式,并且在许多情况下针对任务进行了高度优化,从而提供了一种更有效,更方便的方式来组织它。

A delegate is defined by the signature of the expected method. 委托由预期方法的签名定义。 For instance with: 例如:

public delegate void FooMethod (Bar x, Baz y);

You define a delegate for void methods given a Bar and a Baz . 在给定BarBazvoid方法定义委托。 So if you have an instance of the following class: 因此,如果您有以下类的实例:

public class Qux {

    public void Method (Bar x, Baz y) {
        //do something
        return null;
    }

}

Then you can refer to the method: 然后你可以参考方法:

Qux q = new Qux();
FooMethod fm = q.Method;

An event is thus a list of delegate s with the same signature: 因此, event是具有相同签名的delegate列表:

You define an event as: 您将事件定义为:

private event FooMethod SomeEvent;

You can add delegate s (listeners) by using the += operator: 您可以使用+=运算符添加delegate (侦听器):

SomeEvent += q.Method;

remove the delegate by the -= operator and call the event with: 通过-=运算符删除委托并使用以下命令调用事件:

SomeEvent(new Bar(), new Baz());

As if you call a single method that does the dispatching. 好像你调用一个执行调度的方法。

By calling the event , all the registered delegate s will be called, in the order of registration. 通过调用该event ,将按注册顺序调用所有已注册的delegate

Note : By calling SomeEvent(new Bar(), new Baz()); 注意 :通过调用SomeEvent(new Bar(), new Baz()); this does not mean every delegate receives new instances: the instances are constructed first and shared over all delegate calls. 这并不意味着每个代理都会收到new实例:实例首先构建并在所有代理调用中共享

Conclusion : I think the C# designers did a good job introducing observer patterns since the programmer is no longer responsible to program it correctly his/herself. 结论 :我认为C#设计师在介绍观察者模式方面做得很好,因为程序员不再负责自己正确编程。 Furthermore the events are easy to understand and use convenient syntax. 此外,事件易于理解并使用方便的语法。 In special situations however programmers can be required to implement an observer him/herself. 但在特殊情况下,程序员可能需要自己实施观察者 But these are very rare occasions. 但这些都是非常罕见的场合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM