托付和观察者模式
托付在.Net中应用的很广泛。它实现了对函数的封装,能够当做给方法的特征指定一个名称,将方法当做还有一个方法的參数进行传递,这样的将方法动态地赋给參数的做法,能够避免在程序中使用过多的推断(条件)语句.如今将从我们生活中常见的事情——水沸腾了进行警报,进行对照实现。
一般写法:
<span style="font-family:SimSun;font-size:14px;">//一般的写法()
Public class Heater//热水器{
Private int temperature;
privatevoidBoilWater()
//烧水
{for(inti=0;i<=100;i++)
{temperature=i;
}
}
}
Public class Alarm//警报器
{
Private void MakeAlert(intparam)
{
Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了:",param);
}
}
Public class Display//显示器
{
privatevoidShowMsg(intparam)
{
Console.WriteLine("Display:水已烧开,当前温度:{0}度。",param);
}
}</span><span style="font-size:18px;font-family: KaiTi_GB2312;">
</span>PS:一般写法是从网上找的,重点在于通过托付和观察者模式对上述代码进行改造
托付改造:
加热器类
<span style="font-family:SimSun;font-size:14px;">//使用托付进行简单改造
namespace ConsoleApplication1
{
/// <summary>
/// 加热器类
/// </summary>
class Heater
{
public void BoilWater(int i)
{
Console.WriteLine("当前温度:" + i);
if (BoilWaterMessage != null)<span style="color:#ff0000;">//假设Heater方法被运行时,没有对象注冊事件,则运行BoilWaterMessage</span>
{
BoilWaterMessage();
}
}
public delegate void BoilWaterEventHandler();<span style="color:#ff0000;">//声明一个托付,也就是被监听的事件名称</span>
public event BoilWaterEventHandler BoilWaterMessage;//<span style="color:#ff0000;">声明BoilWaterMessage 事件类型是上面所声明的托付类型</span>
}
}</span><span style="font-family:KaiTi_GB2312;font-size:18px;">
</span>警报类
namespace ConsoleApplication1
{
/// <summary>
/// 警告类
/// </summary>
class Alarm
{
public void MessageAlert()
{
Console.WriteLine("水以沸腾,请注意安全");
}
}
}
client
主执行程序
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Heater heater1 = new Heater();
Alarm alarm1 = new Alarm();
//将警告类的MessageAlert 方法注冊到BoilWaterMessage 托付中
heater1.BoilWaterMessage += new Heater.BoilWaterEventHandler(alarm1.MessageAlert);
//原本BoilWater方法,由于被托付了警告事件,因此显示结果为:当前温度:i 水以沸腾,请注意安全
heater1.BoilWater(100);
Console.Read();
}
}
}
执行结果:
通过托付的改造,我们能够这样:托付与其所注冊的方法具有全然同样的行为。换而言之,被监听对象(Heater)运行某个方法(BoilWater(100))时,注冊在该方法(BoilWater(100))上的被托付方法(MessageAlert ())将会运行,总感觉有点触发器的味道!
观察者模式:
抽象被观察者类:
class AbstractHeater
{
//声明一个观察者集合类
private IList<Alarm> alarms = new List<Alarm>();
//注冊观察者的方法
public void Attach(Alarm alarm)
{
alarms.Add(alarm);
}
/// <summary>
/// 通知
/// </summary>
public void Notify()
{
foreach (Alarm a in alarms)
{
a.Update();
}
}
}
抽象观察者:
abstract class AbstractAlarm
{
public abstract void Update();
}
被观察内容:
/// <summary>
/// 加热器类-被观察者
/// </summary>
class Heater:AbstractHeater
{
private int wendu;
//观察者所关注的东西
public int Wendu
{
get
{
return wendu;
}
set
{
wendu = value;
}
}
}
详细观察者:
/// <summary>
/// 警告类
/// </summary>
class Alarm : AbstractAlarm
{
//观察者依赖被观察者
private Heater heater;
private String message;
public Alarm(Heater heater1, String message1)
{
this.heater = heater1;
this.message = message1;
}
public override void Update()
{
Console.WriteLine("当前温度是{0}度,请{1}加温",heater.Wendu,message);
}
}
client:
class Program
{
static void Main(string[] args)
{
Heater h1 = new Heater();
h1.Attach(new Alarm(h1, "停止"));
h1.Wendu = 100;
h1.Notify();
Console.Read();
}
} 执行结果:
【.Net&&观察者】小结:
细致想想.Net中的托付和观察者模式似乎有着异曲同工之妙。步骤也近乎一样:
声明托付(被观察者)===》》》注冊对象事件(抽象被观察者,不论什么在此注冊的观察者都会被通知)===》》》将被托付的事件进行注冊===》》》托付事件响应,运行被托付事件(被观察者状态改变,观察者进行对应变化)。

浙公网安备 33010602011771号