Henry Instruction - Use the Template Method Design Mode .NET Event Processing Mechanism (1)
By Kevin McFarlane
Henry Translation (2002.10.14)
[HENRY Note: This article is not complex and can be intermediate readers handled by .NET events. Although this article is translated, it is not a completely accurate translation, joining Henry's own views, if there is a fallacy, responsibility is Henry 矣
1 Introduction
Microsoft .NET event processing, like a standard object-oriented architecture, using the famous Observer design mode (see "Design Patterns", Gamma et al., Addison-wesley, 1995, pp325-330) . This article describes how to use Template Method (Henry Note: Template Method, I always don't turn it out more intimate) design mode to enhance .NET's event handling mechanism. The discussion and code snippet is based on C #, but the conclusion example is implemented separately by C # and Visual Basic.net. The idea of this article is from Tomas Restrepo published in "Visual Systems Journal" published in March 2002, which is a standard event processing provided by Microsoft MSDN Library. NET Topics: "Design Guidelines for Class Library Developers" (Details " "Event Use Wizard" section in the article). For event processing, the easiest design is how to trigger an event, not who cares about it, or does different users need to be associated with different methods. 2. Example - Simple Event Processing With such a class: Supplier, when its Name member is set, it will trigger an event, and the class client is used to handle it. Public Class Supplier {public supplier () {} public evenet athamenchanged; [h]
Public String Name
{
Get {return name;}
Set {name = value; onnamechanged ();} [h]
}
Private void onnamechanged ()
{
// After registration, the user can trigger this event.
IF (NameChanged! = null)
NameChanged (this, new evenetargs ());
}
PRIVATE STRING NAME;
}
Public Class Client
{
Public client ()
{
/ / Register for Supplier events
Supplier = new support ();
Supplier.nameChanged = new eventhandler (_this.supplier_namechanged); [H]
}
Public void testEvent ()
{
// Set up NAME to generate an event
Supplier.name = "kevin mcfarlane";
}
Private void sales_namechanged (Object Sender, _ Eventargs E) [h]
{
// Handle the Supplier event
}
Private Supplier Supplier;
}
[Henry Note: In this example, we can learn from the C # to customize an event and process it. Please pay attention to the code of [H]]. The user of an event can be an external or inside. A "external" user means that an event can be executed, but it is nothing to do with the class that triggered this event. In other words, it is not part of the event class inherits the tree. The CLIENT class in the example is an external user. A "internal" user can be an event generating class itself (if it processes the own event at the same time), or a derived class of the event. In this case, the simple design above said that is not enough. Users cannot easily change the change to occur when the event is triggered, or the default line for processing events. In order to cope with this problem, in the .NET Design Guides for Class Library Developers, Microsoft recommends using a protected Virtual Method to trigger each event. This provides a method for handling an event by rewriting. Therefore, in our example, OnNameChanged () should write like the following example: protected virtual void onnamechanged () {
// After registration, the user can trigger this event.
IF (NameChanged! = null)
NameChanged (this, new evenetargs ());
}
Microsoft immediately said: "Derive class when processing oneventname (Henry Note: OneventName is similar to an event trigger method of ONNAMECHANGED), you can choose not to invoke the base class. To do this, you have to do any processing in the onportname method to facilitate the basis The class works correctly. "
This has a problem. In general, OnNameChanged () can do some default processing before triggering events. Override OnNameChanged () can achieve different processes. But to ensure that the external user is working properly, it must call the base class. If it cannot call the base class, the event cannot be used for external users. Forgot to call the base class of the triggering event, it violates the Polymorphic Substitution of Liskov (Henry Note: Data Abstract and Hierarchy, the classic article of Barbara Liskov, the Massachusetts Institute of Science, Data Abstract and Hierarchy, this article Small changes): Use the reference to the reference to the base class, must be able to use them without knowing the specific derived object type. Fortunately, there is now a solution.
3. Template Method Design Mode
The purpose of the Template Method design mode is to define an algorithm as a fixed operation step, but there is one or more steps to change. (Henry Note: Variations usually refer to a description and execution of certain steps to subclasses) In our example, algorithm can consist of trigger events and their responses. There is a response when there is a change. Therefore, the decision is that it is separated from the part. We divide overnameChanged () into two methods: interNalonNameChanged () and onnamechanged (). INTERNALONNAMECHANGED () calls OnNameChanged () to perform the default process, then trigger the event.
Private voidinnamechanged ()
{
// Derived class rewritten default behavior
ONNAMECHANGED ();
// After registration, the user can trigger this event.
IF (NameChanged! = null) NameChanged (this, new evenetargs);
}
protected virtual void onnamechanged ()
{
/ / Execute the default behavior here
}
The Name property is changed to:
Get {return name;}
Set {name = value; internaMechanged ();
The benefits of using this method are:
1) In this example of this trigger event, it is an important step in the base class to avoid failure of the derived class calling base class. Therefore, external users can get more reliable services; 2) The derived class can do not worry, and safely replace the default behavior of the base class in ONNAMECHANGED (). E-mail: ruigeren@sina.com QQ: 18349592 ---- Declaration: The right to copyright and interpretation of this article belongs to Han Rui, if you need to reprint, please keep your full content and this statement.