用C#的多播实现publish-subscribe模式

用C#的多播实现publish-subscribe模式

模拟这样一个情景。一个加热器(Heater)和一个冷却器(Cooler)连接到一个温度自动调节器。当温度变化时,温度调节器把温度传给它的订阅者,也就是Heater和Cooler

Heater类

class  Heater
    {
        
private   int  _Temperature;

        
public  Heater( int  Temperature)
        {
            _Temperature 
=  Temperature;
        }

        
public   int  Temperature
        {
            
get
            {
                
return  _Temperature;
            }
            
set
            {
                _Temperature 
=  value;
            }
        }

        
public   void  OnTemperatureChanged( int  NewTemperature)
        {
            
if  (NewTemperature  >  _Temperature)
            {
                Console.WriteLine(
" Heater On " );
            }
            
else
            {
                Console.WriteLine(
" Heater Off " );
            }
        }
    }

Cooler类
  class  Cooler
    {
        
private   int  _Temperature;

        
public  Cooler( int  Temperature)
        {
            _Temperature
= Temperature;
        }

        
public   int  Temperature
        {
            
get
            {
                
return  _Temperature;
            }
            
set
            {
                _Temperature
= value;
            }
        }

        
public   void  OnTemperatureChanged( int  NewTemperature)
        {
            
if  (NewTemperature  <  _Temperature)
            {
                Console.WriteLine(
" Cooler On " );
            }
            
else  
            {
                Console.WriteLine(
" Cooler Off " );
            }
        }
    }


发布者(温度调节器)

  public   class  Thermostate
    {
        
public   delegate   void  TemperatureChangedHandle( int  NewTemperature);

        
private   int  _Temperature;
        
private  TemperatureChangedHandle _OnTemperatureChanged;

        
public  TemperatureChangedHandle OnTemperatureChanged
        {
            
get  {  return  _OnTemperatureChanged; }
            
set  { _OnTemperatureChanged  =  value; }
        }

        
public   int  Temperature
        {
            
get  {  return  _Temperature; }
            
set  
            {
                
if  (value  !=  _Temperature)
                {
                    _Temperature 
=  value;
                    TemperatureChangedHandle tmpOnTemperatureChanged 
=  _OnTemperatureChanged;
                    
if  (tmpOnTemperatureChanged  !=   null )
                    {
                        tmpOnTemperatureChanged(_Temperature);
                    }
                }
            }
        }
    }


在Main函数中让Heater和Cooler的实例订阅Thermostat
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);
        }        
    }


注意Thermostat类的实现中,当温度改变时,调用委托的实例。但是在调用之前要先判断一下委托是否为空,如果为空,调用时就会引发异常。
判断委托是否为空时,我先把当前的委托赋值给了另外一个委托变量。这个简单的修改可以确保在检查空值和发送通知之间,假如所有的订阅者都被移除了(由另外一个不同的县城),那么也不会触发异常。
(为什么呢?我把当前的委托赋值给了一个局部委托变量,那么这两个委托不是应该指向同一个引用吗?如果一个改变为空了,另一个不是也为空了吗?事实上,当在_OnTemperatureChanged上调用-=时,并没有直接修改_OnTemperatureChanged所引用的对象,而是返回了一个新的委托对象,有点像String类型。所以_OnTemperatureChanged上调用-=时,tmpTemperatureChanged并没有变化)

切记:调用委托前,先检查它的值是否为空







你可能感兴趣的:(用C#的多播实现publish-subscribe模式)