** Henry ** ** 手记 ** ** — ** ** 使用 ** ** Template Method ** ** 设计模式 ** ** 的 **
** ** ** .NET ** ** 事件处理机制(二) ** ** **
** By Kevin McFarlane ** ** **
韩睿 译 (2002.10.14)
** 4. ** 示例—Template Method设计模式事件处理
下文是一段完整的用 C# 与 Visual Basic.Net 实现的示例。它由三个类组成: Supplier
, ExternalClient
和 InternalClient
。
Supplier
触发事件。另两个类执行该事件。
InternalClient
由
Supplier
派生而来。
ExternalClient
包括一个嵌入的
Supplier
的引用。然而,它由一个
InternalClient
引用初始化。因此,当
ExternalClient
为
Supplier
事件进行注册时,它调用了
InternalClient
重写的
OnNameChanged()
。然后该事件由
InternalClient
的
NameChanged()
处理,最后由
ExternalClient
的
NameChanged()
处理。
代码的输出为:
InternalClient.OnNameChanged
InternalClient.NameChanged
ExternalClient.NameChanged
- C#示例:
using System;
class Test
{
static void Main( string [] args)
{
ExternalClient client = new ExternalClient();
client.TestSupplier();
}
}
_ // 当它的属性被设置时,产生一个事件 _
public class Supplier
{
public Supplier() {}
public event EventHandler NameChanged;
public string Name
{
get { return name; }
set { name = value; InternalOnNameChanged(); }
}
_ // _ _ 内部使用者,也就是派生类,可以重写默认行为 _
protected virtual void OnNameChanged()
{
_ // _ _ 在此执行默认行为 _
Console.WriteLine("Supplier.OnNameChanged");
}
_ // _ _ 如果内部使用者(派生类)在 OnNameChanged 中重写了默认行为,外部使用者仍将接受到此事件 _
private void InternalOnNameChanged()
{
_ // _ _ 派生类可重写默认行为 _
OnNameChanged();
_ // _ _ 在注册后,使用者即可触发此事件 _
if (NameChanged != null )
NameChanged( this , new EventArgs());
}
private string name;
}
_ // 一个处理 Supplier.NameChanged 事件的“内部”使用者,但首先要重写它的默认行为 _
public class InternalClient : Supplier
{
public InternalClient()
{
NameChanged += new EventHandler( this .Supplier_NameChanged);
}
protected override void OnNameChanged()
{
_ // _ _ 重写 Supplier.NameChanged 的默认行为 _
Console.WriteLine("InternalClient.OnNameChanged");
}
private void Supplier_NameChanged( object sender, EventArgs e)
{
_ // _ _ 处理 Supplier.NameChanged _
Console.WriteLine("InternalClient.NameChanged");
}
}
_ // 一个处理 Supplier.NameChanged 事件的“外部”使用者 . _
public class ExternalClient
{
public ExternalClient()
{
_ // _ _ 将 supplier 实例化为一个 InternalClient 实例的引用。当一个事件被唤起时,它会触发重写的 InternalClient.OnNameChanged _
supplier = new InternalClient();
supplier.NameChanged += new EventHandler( this .supplier_NameChanged);
}
public void TestSupplier()
{
_ // _ _ 下面代码会触发一个事件,并由 InternalClient 和 ExternalClient 的 handlers 来处理 _
supplier.Name = "Kevin McFarlane";
}
private void supplier_NameChanged( object sender, EventArgs e)
{
_ // _ _ 处理 Supplier.NameChanged _
Console.WriteLine("ExternalClient.NameChanged");
}
private Supplier supplier;
}
- VB.NET示例:
Module Test
Sub Main() _ ‘ 程序入口 _
Dim client As ExternalClient = New ExternalClient()
client.TestSupplier()
End Sub
End Module
_ ' 当它的属性被设置时,产生一个事件 _
Public Class Supplier
Sub New ()
End Sub
Public Event NameChanged As EventHandler
Public Property Name() As String
Get
Return mName
End Get
Set ( ByVal Value As String )
mName = Value
InternalOnNameChanged()
End Set
End Property
_ ' _ _ 内部使用者,也就是派生类,可以重写默认行为 _
Protected Overridable Sub OnNameChanged()
_ ' _ _ 在此执行默认行为 _
Console.WriteLine("Supplier.OnNameChanged")
End Sub
Private Sub InternalOnNameChanged()
_ ' _ _ 派生类可重写默认行为 _
OnNameChanged()
_ ' _ _ 为使用者唤起事件 _
RaiseEvent NameChanged(Me, New EventArgs())
End Sub
Private mName As String
End Class
_ ' 一个处理 Supplier.NameChanged 事件的 “ 内部 ” 使用者 , 但首先要重写它的默认行为 _
Public Class InternalClient
Inherits Supplier
Sub New ()
End Sub
Protected Overrides Sub OnNameChanged()
_ ' _ _ 重写 Supplier.NameChanged 的默认行为 _
Console.WriteLine("InternalClient.OnNameChanged")
End Sub
Private Sub Supplier_NameChanged( ByVal sender As Object, ByVal e As EventArgs) _ Handles MyBase.NameChanged
_ ' _ _ 处理 Supplier.NameChanged _
Console.WriteLine("InternalClient.NameChanged")
End Sub
End Class
_ ' 一个处理 Supplier.NameChanged 事件的“外部”使用者 . _ <