1. 程式人生 > >觀察者模式的經典應用(貓叫 燒開水)

觀察者模式的經典應用(貓叫 燒開水)

using System;
using System.Collections.Generic;
using System.Text;

namespace Delegate {
    // 熱水器
    public class Heater {
       private int temperature;
       public string type = "RealFire 001";       // 新增型號作為演示
       public string area = "China Xian";         // 新增產地作為演示
       //宣告委託
       public delegate void
BoiledEventHandler(Object sender, BoiledEventArgs e);
       public event BoiledEventHandler Boiled; //宣告事件

       // 定義BoiledEventArgs類,傳遞給Observer所感興趣的資訊
       public class BoiledEventArgs : EventArgs {
           public readonly int temperature;
           public BoiledEventArgs(int temperature) {
              this
.temperature = temperature;
           }
       }

       // 可以供繼承自 Heater 的類重寫,以便繼承類拒絕其他物件對它的監視
       protected virtual void OnBoiled(BoiledEventArgs e) {
           if (Boiled != null) { // 如果有物件註冊
              Boiled(this, e);  // 呼叫所有註冊物件的方法
           }
       }
      
       // 燒水。
       public void BoilWater() {
           for
(int i = 0; i <= 100; i++) {
              temperature = i;
              if (temperature > 95) {
                  //建立BoiledEventArgs 物件。
                  BoiledEventArgs e = new BoiledEventArgs(temperature);
                  OnBoiled(e);  // 呼叫 OnBolied方法
              }
           }
       }
    }

    // 警報器
    public class Alarm {
       public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
           Heater heater = (Heater)sender;     //這裡是不是很熟悉呢?
           //訪問 sender 中的公共欄位
           Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Alarm: 嘀嘀嘀,水已經 {0} 度了:", e.temperature);
           Console.WriteLine();
       }
    }

    // 顯示器
    public class Display {
       public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) {   //靜態方法
           Heater heater = (Heater)sender;
           Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Display:水快燒開了,當前溫度:{0}度。", e.temperature);
           Console.WriteLine();
       }
    }

    class Program {
       static void Main() {
           Heater heater = new Heater();
           Alarm alarm = new Alarm();

           heater.Boiled += alarm.MakeAlert;   //註冊方法
           heater.Boiled += (new Alarm()).MakeAlert;      //給匿名物件註冊方法
           heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert);    //也可以這麼註冊
           heater.Boiled += Display.ShowMsg;       //註冊靜態方法

           heater.BoilWater();   //燒水,會自動呼叫註冊過物件的方法
       }
    }
}

輸出為:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已經 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已經 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已經 96 度了:
Display:China Xian - RealFire 001:
Display:水快燒開了,當前溫度:96度。