Henry手记—使用Template Method设计模式的.NET事件处理机制(二)

** Henry ** ** 手记 ** ** — ** ** 使用 ** ** Template Method ** ** 设计模式 ** ** 的 **

** ** ** .NET ** ** 事件处理机制(二) ** ** **

** By Kevin McFarlane ** ** **

韩睿 译 (2002.10.14)


** 4. ** 示例—Template Method设计模式事件处理

下文是一段完整的用 C# 与 Visual Basic.Net 实现的示例。它由三个类组成: Supplier , ExternalClientInternalClient Supplier 触发事件。另两个类执行该事件。 InternalClient Supplier 派生而来。

ExternalClient 包括一个嵌入的 Supplier 的引用。然而,它由一个 InternalClient 引用初始化。因此,当 ExternalClient Supplier 事件进行注册时,它调用了 InternalClient 重写的 OnNameChanged() 。然后该事件由 InternalClient NameChanged() 处理,最后由 ExternalClient NameChanged() 处理。

代码的输出为:

InternalClient.OnNameChanged

InternalClient.NameChanged

ExternalClient.NameChanged

  1. 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;

}

  1. 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 事件的“外部”使用者 . _ <


Published At
Categories with Web编程
Tagged with
comments powered by Disqus