委托是一个类,它定义了一种方法类型,使得方法可以像其他普通类型一样作为参数被传递,但它与普通类型的区别是,可以将多个方法实例绑定到一个委托实例上,调用的时候,依次执行。委托带来的好处是,提升程序的可扩展性,解决if/else(或Switch)的问题。
用到委托的地方: 当涉及到针对某一相同的输入,需要根据情况去执行不同的逻辑或产生不同的输出时,通常会需要if/else或者switch来实现,可以考虑引入委托。
事件实际是委托的一个封装,当把一个委托定义为某个类的成员时,如果声明为public又恐暴露给客户端随意更改,违背了封装性,声明为private,又违背了给客户端使用的本意,故而采用和普通类型对应的属性的方法来解决,event就可以看成是delegate变量的属性。形如public event ***delegate ***;
.net framework 定义的EventHandler是一种通用的委托,其接受object和EventArgs参数。为了维护事件的封装性,在类的外部,事件只提供注册和注销,不供调用,调用只能在内部进行,而内部通常有订阅事件的方法,通常以"On事件名"为名称,例如page的OnInit,OnLoad等。
Asp.net 中,事件是一块典型的应用。就拿System.Web.UI.Page类来讲,页面生命周期是由一系列事件组成,在ProcessRequest中定义了这一流程。例如,首先执行OnPreInit方法,这个方法调用了PreInit事件,如果客户端的某些函数注册了该PreInit事件,那么将会被依次执行,其他的事件同样如此。
Observer是一种设计模式。它通常用来解决对象的一对多的依赖的问题。它有2种类型,主题和观察者。主题订阅或取消观察者,当主题某一变化发生时,将通知观察者,进行Update的逻辑。这和事件的原理是一样的。
Observer模式又分为推模式和拉模式,它们的区别在于在主题发生变化时,推模式调用观察者对象,传递数据参数(数据参数包含主题的一些信息),而拉模式,主题直接将自身引用传递给观察者对象。前者麻烦在于需要定义数据参数EventArgs,但对主题对象保护比较好,至少没把引用暴露出去;后者不需要实现数据参数,但却容易引起主题被胡乱修改。.net framework定义的 EventHandler(object sender, EventArgs e)同时使用了这2种模式。