Case study of event Commission

Source: Internet
Author: User
Tags prototype definition

If we have a high-end water heater, we can power it on. When the water temperature exceeds 95 degrees: 1. The speaker will start to send a voice to tell you the temperature of the water; 2. the LCD screen will also change the display of the water temperature to prompt that the water has been burned out.

Now we need to write a program to simulate the water burning process. We will define a class to represent the water heater. We call it heater, which has a field representing the water temperature, called temperature; of course, there is also an essential method of water supply heating, boilwater (), a method of Voice Alarm makealert (), a method of displaying water temperature, showmsg ().

Copy codeThe Code is as follows: namespace delegate {

Class heater {

Private int temperature; // Water Temperature

// Boil water

Public void boilwater (){

For (INT I = 0; I <= 100; I ++ ){

Temperature = I;

If (temperature> 95 ){

Makealert (temperature );

Showmsg (temperature );

}

}

}

// Send a voice alarm

Private void makealert (int param ){

Console. writeline ("alarm: Tick, water has been {0} degrees:", Param );

}

// Display the water temperature

Private void showmsg (int param ){

Console. writeline ("display: The water is almost open. Current temperature: {0. ", Param );

}

}

Class program {

Static void main (){

Heater ht = new heater ();

Ht. boilwater ();

}

}

}

Introduction to the Observer Design Mode
The above example can obviously complete the work we described earlier, but it is not good enough. It is assumed that the water heater is composed of three parts: water heater, alarm, and display, which are from different manufacturers and assembled. Then, the water heater is only responsible for boiling water. It cannot issue an alarm or display the water temperature. When boiling water, an alarm is triggered by an alarm, a display prompt, and a water temperature.

At this time, the above example should look like this:

// Water Heater

Copy codeThe Code is as follows: public class heater {

Private int temperature;

// Boil water

Private void boilwater (){

For (INT I = 0; I <= 100; I ++ ){

Temperature = I;

}

}

}

// Alarm

Public class alarm {

Private void makealert (int param ){

Console. writeline ("alarm: Tick, water has been {0} degrees:", Param );

}

}

// Display

Public class display {

Private void showmsg (int param ){

Console. writeline ("display: the water has been burned out. Current temperature: {0. ", Param );

}

}

There is a problem: how to notify the alarm and display when the water is turned on? Before proceeding, let's take a look at the observer design mode. The observer design mode mainly includes the following two types of objects:

Subject: A monitoring object, which usually contains content of interest to other objects. In this example, the water heater is a monitoring object, and the content that other objects are interested in is the temprature field. When the value of this field is approaching 100, the data is constantly sent to the object that monitors it. Observer: The monitor that monitors subject. When something in a subject occurs, it notifies observer, and the observer takes corresponding action. In this example, the observer has an alarm and a monitor, and they take the action of issuing an alarm and displaying the water temperature respectively. In this example, the sequence of events should be as follows:

The alarm and monitor tell the water heater that it is interested in its temperature (registered ). The water heater retains reference to alarms and monitors after it is known. When the water temperature exceeds 95 degrees, the water heater automatically calls the makealert () method of the alarm and the showmsg () method of the monitor by referencing the alarm and display. There are many examples like this. gof abstracts it and is called the observer design pattern: The Observer Design Pattern aims to define a one-to-many dependency between objects, so that when the state of an object changes, other objects dependent on it will be automatically notified and updated. The observer mode is a loosely coupled design mode.

Observer Design Mode for implementing examples
We have already introduced a lot of delegation and events before, and it should be easy to write code now. Now we will give the code directly here and explain it in the annotations.

Copy codeThe Code is as follows: using system;

Using system. Collections. Generic;

Using system. text;

Namespace delegate {

// Water Heater

Public class heater {

Private int temperature;

Public Delegate void boilhandler (int param); // declare the delegate

Public event boilhandler boilevent; // declare an event

// Boil water

Public void boilwater (){

For (INT I = 0; I <= 100; I ++ ){

Temperature = I;

If (temperature> 95 ){

If (boilevent! = NULL) {// if an object is registered

Boilevent (temperature); // call the methods of all registered objects

}

}

}

}

}

// Alarm

Public class alarm {

Public void makealert (int param ){

Console. writeline ("alarm: Tick, water has been {0} degrees:", Param );

}

}

// Display

Public class display {

Public static void showmsg (int param) {// static method

Console. writeline ("display: The water is almost burned out. Current temperature: {0. ", Param );

}

}

Class program {

Static void main (){

Heater heater = new heater ();

Alarm alarm = new alarm ();

Heater. boilevent + = alarm. makealert; // Registration Method

Heater. boilevent + = (new alarm (). makealert; // Method for registering anonymous objects

Heater. boilevent + = display. showmsg; // register the static method

Heater. boilwater (); // The method of boiling water, which automatically calls the method of registering an object

}

}

}

Output:

Alarm: The water is 96 degrees away:

Alarm: The water is 96 degrees away:

Display: the water is boiling. The current temperature is 96 degrees.

// Omit...

Edit delegation and events in this section. NET Framework
Although the above example completes what we want to do, we are not only confused: Why is the event model in. NET Framework different from the above? Why are there many eventargs parameters?

Before answering the above questions, we should first understand the encoding specifications of. NET Framework:

The name of the delegate type should end with eventhandler. Prototype definition of the delegate: There is a void returned value, and two input parameters are accepted: an object type, and an eventargs type (or inherited from eventargs ). The event is named as the part left after the eventhandler is removed by the delegate. The types inherited from eventargs should end with eventargs. Next, let's explain:

The parameter of the object type in the delegate declaration prototype represents the subject, that is, the Monitored object. In this example, it is the heater (water heater ). A callback function (such as makealert of alarm) can be used to access the event-triggered object (heater ). The eventargs object contains the data that the observer is interested in. In this example, It is temperature. In fact, the above is not only for coding specifications, but also makes the program more flexible. For example, if we not only want to get the temperature of the water heater, but also want to get its production date, model, and price in the observer side (alarm or display) method, the delegation and method declaration will become very troublesome. If we pass the water heater reference to the method of the alarm, we can directly access the water heater in the method.

Now we can rewrite the previous example to make it conform to. NET Framework specifications:

Copy codeThe Code is as follows:

Using system;

Using system. Collections. Generic;

Using system. text;

Namespace delegate {

// Water Heater

Public class heater {

Private int temperature;

Public string type = "realfire 001"; // Add a model for demonstration

Public String area = "China Xian"; // Add the origin as a demo

// Declare the delegate

Public Delegate void boiledeventhandler (Object sender, boiledeventargs E );

Public event boiledeventhandler boiled; // declare the event

// Define the boiledeventargs class and pass the information to the observer.

// Inherit eventargs

Public class boiledeventargs: eventargs {

Public readonly int temperature ;//

Public boiledeventargs (INT temperature ){

This. temperature = temperature;

}

}

// The class inherited from heater can be rewritten so that the inherited class rejects the monitoring of other objects.

Protected virtual void onboiled (boiledeventargs e ){

If (boiled! = NULL) {// if an object is registered

Boiled (this, e); // call the method of all registered objects

}

}

// Boil water.

Public void boilwater (){

For (INT I = 0; I <= 100; I ++ ){

Temperature = I;

If (temperature> 95 ){

// Create a boiledeventargs object.

Boiledeventargs E = new boiledeventargs (temperature );

Onboiled (E); // call the onboiled Method

}

}

}

}

// Alarm

Public class alarm {

Public void makealert (Object sender, heater. boiledeventargs e ){

Heater heater = (heater) sender; // are you familiar with this?

// Access public fields in sender

Console. writeline ("alarm: {0}-{1}:", heater. Area, heater. type );

Console. writeline ("alarm: Tick, water has {0} degrees:", E. Temperature );

Console. writeline ();

}

}

// Display

Public class display {

Public static void showmsg (Object sender, heater. boiledeventargs e) {// static method

Heater heater = (heater) sender;

Console. writeline ("display: {0}-{1}:", heater. Area, heater. type );

Console. writeline ("display: The water is almost burned out. Current temperature: {0. ", E. Temperature );

Console. writeline ();

}

}

Class program {

Static void main (){

Heater heater = new heater ();

Alarm alarm = new alarm ();

Heater. Boiled + = alarm. makealert; // Registration Method

Heater. Boiled + = (new alarm (). makealert; // Method for registering anonymous objects

Heater. Boiled + = new heater. boiledeventhandler (alarm. makealert); // You can also register

Heater. Boiled + = display. showmsg; // register the static method

Heater. boilwater (); // The method of boiling water, which automatically calls the method of registering an object

}

}

}

Output:

Alarm: China Xian-realfire 001:

Alarm: The water is 96 degrees away:

Alarm: China Xian-realfire 001:

Alarm: The water is 96 degrees away:

Alarm: China Xian-realfire 001:

Alarm: The water is 96 degrees away:

Display: China Xian-realfire 001:

Display: the water is boiling. The current temperature is 96 degrees.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.