Observer模式

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

软件设计模式在软件架构中的应用
Observer模式在.net架构中的应用
1.简介
在.NET Framework中,关于事件与委托的处理就采用了Observer模式。

事件的发布者,就是Subject角色;而事件的订阅者,则为Observer角色。

例如,Button控件发布了Click事件,当一个窗体对象创建了Button实例时,如果需要在点击Button对象后进行相应的操作,就可以订阅Button的Click事件。

在这样的实现方式里,Button对象不依赖于任何可能将订阅Click事件的Observer;而对于Observer而言,在订阅Click事件时,它只需要知道该事件的委托类型,即EventHandler。

由于委托类型相当于是一组方法签名相同的方法,与接口不同,因此具体的Observer类就不受接口实现的限制,使得Observer 角色与Subject角色之间的依赖大大地减弱,实现了解耦的目的。

由于委托与接口的差别,与GOF关于Observer模式的实现方案相比,利用事件与委托在解耦性方面具有一定的优势,因此,本节将引入事件与委托机制对上一节的实现方案进行修改。

首先,需要定义一个委托类型,它指代的方法签名应该与之前IStateChangeable中的接口方法FindAndChangeEQPState相同。

public delegate void ChangeEQPStateHandler(Equipment eqp);
接着修改Subject角色,也就是IStateNotifier接口对象,它应该是事件的发布者。

在接口中定义事件是没有问题的,不过鉴于需求对消息通知者的要求,在此,我简化了Subject角色的定义,直接以类StateNotifier来完成。

public class StateNotifer
{
public event ChangeEQPStateHandler ChangeEQPStateEvent; public void Attach(ChangeEQPStateHandler handler)
{
ChangeEQPStateEvent += handler;
}
public void Detach(ChangeEQPStateHandler handler)
{
ChangeEQPStateEvent -= handler;
}
public void ChangeState(Equipment eqp)
{
if (ChangeEQPStateEvent != null)
{
ChangeEQPStateEvent(eqp);
}
}
}
2.OperatorForm与ManufactureForm类
由于引入了ChangeEQPStateHandler委托,因而可以删去原来作为抽象Observer角色的IStateChangeable接口。

作为具体Observer角色的两个窗体类OperatorForm与ManufactureForm,则修改其实现如下。

public class OperatorForm:System.Windows.Forms.Form
{
public OperatorForm(StateNotifier notifier)
{
notifier.Attach(new ChangeEQPStateHandler(this.FindAndChangeEQPState));
}
//与ChangeEQPStateHandler委托一致的方法
private void FindAndChangeEQPState(Equipment eqp)
{
//实现略
}
}
public class ManufactureForm:System.Windows.Forms.Form
{
public ManufactureForm(StateNotifier notifier)
{
notifier.Attach(new ChangeEQPStateHandler(this.FindAndChangeEQPState));
}
//与ChangeEQPStateHandler委托一致的方法
private void FindAndChangeEQPState(Equipment eqp)
{
//实现略
}
}
在OperatorForm和ManufactureForm类中,我们通过构造函数将StateNotifier对象传入,然后调用StateNotifier的Attach方法。

StateNotifier类中定义的Attach和Detach方法,其职责是将委托对象ChangeEQPStateHandler添加或移除委托链。

如果参照.NET Framework中Button 的实现方式,完全可以去掉这两个方法,直接利用C#提供的+=与 =运算符实现。

此外,为了更好地调用StateNotifier对象,我们可以将其定义为一个全局变量,放到类Utility中。

修改后的完整实现如下所示。

public class StateNotifer
{
public event ChangeEQPStateHandler ChangeEQPStateEvent;
public void ChangeState(Equipment eqp)
{
if (ChangeEQPStateEvent != null)
{
ChangeEQPStateEvent(eqp);
}
}
}
public static Class Utility
{
public static StateNotifier Notifier = new StateNotifier(); }
public class MainForm:System.Windows.Forms.Form
{
private Equipment m_eqp;
private Timer timer;
private IContainer components;
public MainForm()
{
OperatorForm opForm = new OperatorForm();
ManufactureForm maForm = new ManufactureForm();
opForm.Show();
maForm.Show();
InitializeComponent();
}
private void InitializeComponent()
{
//其他略
this.timer.Enabled = true;
this.timer.Interval = 1000;
this.timer.Tick += new System.EventHandler(this.timer_Tick); }
private void timer_Tick(object sender, EventArgs e)
{
//获取服务端消息
//判断状态是否改变
if (IsChanged())
{
Utility.Notifier.ChangeState(m_eqp);
}
private bool IsChanged()
{
return true;
}
}
public class OperatorForm:System.Windows.Forms.Form
{
public OperatorForm()
{
InitializeComponent();
Utility.Notifier.ChangeEQPStateEvent += new ChangeEQPStateHandler(this.FindAndChangeEQPState);}
private void FindAndChangeEQPState(Equipment eqp)
{
//实现略
}
}
public class ManufactureForm:System.Windows.Forms.Form
public ManufactureForm ()
{
InitializeComponent();
Utility.Notifier.ChangeEQPStateEvent += new ChangeEQPStateHandler(this.FindAndChangeEQPState);
}
private void FindAndChangeEQPState(Equipment eqp)
{
//实现略
}
}
利用事件与委托实现Observer模式,可以不受Observer角色中接口方法的限制。

在上述的实现方案中,OperatorForm类的FindAndChangeEQPState方法名是没有限制的,只要该方法符合委托ChangeEQPStateHandler的方法签名即可。

因此,我们可以在Observer角色中定义一系列符合委托ChangeEQPStateHandler方法签名的方法,然后利用委托链的机制,将这些方法添加到事件ChangeEQPStateEvent中。

由于.NET Framework自身提供了对委托链的管理,因而在实现中可以省略添加和移除Observer对象的方法。

如此的实现与上一节相比,实不可同日而语,应该是更加灵活了。

故而在.NET中,如果需要实现Observer模式,我强烈建议利用事件与委托来完成整个设计。

相关文档
最新文档