上一篇文章讲的用多播实现订阅者模式。
但是这样还是有些问题。
如果我直接调用了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判断是哪个实例触发了事件