上一篇文章講的用多播實現訂閱者模式。
但是這樣還是有些問題。
如果我直接調用了thermostat.OnTemperatureChanged(20),那么不管溫度有沒有變化,都會觸發所有thermostat訂閱者的一個通知。這是因為委托不充分。應該禁止其他類調用OnTemperatureChanged委托。可以通過event關鍵字解決這個問題。
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
namespace Happy
{
class Cooler
{
private int _Temperature;
public Cooler(int Temperature)
{
_Temperature=Temperature;
}
public int Temperature
{
get
{
return _Temperature;
}
set
{
_Temperature=value;
}
}
public void OnTemperatureChanged(object sender,Thermostate.TemperatureArgs NewTemperature)
{
if (NewTemperature.Temperature < _Temperature)
{
Console.WriteLine("Cooler On");
}
else
{
Console.WriteLine("Cooler Off");
}
}
}
class Heater
{
private int _Temperature;
public Heater(int Temperature)
{
_Temperature = Temperature;
}
public int Temperature
{
get
{
return _Temperature;
}
set
{
_Temperature = value;
}
}
public void OnTemperatureChanged(object sender, Thermostate.TemperatureArgs NewTemperature)
{
if (NewTemperature.Temperature > _Temperature)
{
Console.WriteLine("Heater On");
}
else
{
Console.WriteLine("Heater Off");
}
}
}
public class Thermostate
{
public class TemperatureArgs : EventArgs
{
public TemperatureArgs(int NewTemperature)
{
_Temperature = NewTemperature;
}
public int Temperature
{
get { return _Temperature; }
set { _Temperature = value; }
}
private int _Temperature;
}
public delegate void TemperatureChangedHandle(object sender,TemperatureArgs NewTemperature);
public event TemperatureChangedHandle OnTemperatureChanged;
private int _Temperature;
public int Temperature
{
get { return _Temperature; }
set
{
if (value != _Temperature)
{
_Temperature = value;
TemperatureChangedHandle tmpOnTemperatureChanged = OnTemperatureChanged;
if (tmpOnTemperatureChanged != null)
{
tmpOnTemperatureChanged(this,new TemperatureArgs(_Temperature));
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
Thermostate thermostat = new Thermostate();
Cooler cooler = new Cooler(60);
Heater heater = new Heater(80);
string Temperature;
thermostat.OnTemperatureChanged += cooler.OnTemperatureChanged;
thermostat.OnTemperatureChanged += heater.OnTemperatureChanged;
Temperature = Console.ReadLine();
thermostat.Temperature = Convert.ToInt32(Temperature);
}
}
}
這樣,用event定義的OnTemperatureChanged就只能出現在+=或者-=得左邊了。
并且這樣還可以通過sender參數判斷是哪個publisher觸發了事件。假如heater訂閱了兩個Thermostat實例,就可以通過sender判斷是哪個實例觸發了事件