在极其简单的示例中实现观察者模式






2.84/5 (21投票s)
使用事件和委托在 C# 中实现观察者模式。

引言
当您开发应用程序时,我相信您必须处理几个对象。
如果它们需要与同一个源数据交互,我认为您必须找到一种方法来使用数据的更改来更新它们。观察者模式是您可用于此解决方案的关键!
背景
我在该网站上搜索了,发现了一些关于观察者模式的文章。我也阅读了一些关于事件和委托的文章。我想向您——新开发者——展示一种实现观察者模式最简单、最快捷、最易于理解的方式。
现在,让我们开始吧!
Using the Code
我在 Winforms 中创建了一个示例,使用 .NET Framework 2.0 中的 C# 语言。
- 我有 2 个窗体:
Form2
和Form3
。
- 在
form2
中,有 3 个单选按钮、一个Label
和一个Button
。如果您选中单选按钮,您会发现标签的前景色将根据单选按钮的名称更改颜色。这很简单,不是吗?- 当您单击按钮打开子窗体时,
Form3
将显示!如果您再次选中单选按钮,除了标签的前景色更改外,您还会发现 Form3 中文本框的背景色也将被更改!就是这样!
- 此解决方案中有 2 个对象
Subject
(主题):它将是父级!当客户端被创建时,客户端必须向该主题注册。当发生变化时,主题将通知它管理的所有客户端以更新它们。Observer
(观察者):它是客户端。当它被创建时,它必须向主题注册,并等待在发生变化时进行更新。
主题对象
首先,我创建一个委托和一个事件,以便在发生变化时使其“活跃”!
private delegate void NotifyHandler(string _color);
private event NotifyHandler NotifyEvent;
我还创建了一个名为 arrObs
的 ArrayList
来管理所有注册到 Subject
对象中的客户端对象。
ArrayList arrObs = new ArrayList();
主题的完整详细信息在此
public class Subject
{
ArrayList arrObs = new ArrayList();
private delegate void NotifyHandler(string _color);
private event NotifyHandler NotifyEvent;
public Subject()
{
this.NotifyEvent += new NotifyHandler(Notify);
}
public void UpdateClient(string _color)
{
OnNotify(_color);
}
private void OnNotify(string _color)
{
if (NotifyEvent != null)
{
NotifyEvent(_color);
}
}
private void Notify(string _color)
{
for (int i = 0; i < arrObs.Count; i++)
{
Observer obs = (Observer)arrObs[i];
obs.Update(_color);
}
}
public void RegisterClient(Observer obs)
{
arrObs.Add(obs);
}
}
您将看到,当主题被创建时,它将 NotifyEvent
与 Notify
方法注册。在 Notify()
中,它将 _color
字符串传递给 arrObs
中的所有客户端。客户端将调用 Update
方法来更新颜色。
现在,让我们看看名为 Observer
的客户端对象!
观察者对象
与 Subject
对象一样,我将定义一个委托和一个事件,以便在主题通知它们时使其“活跃”!
private delegate void ColorEventHandler(string _color);
private event ColorEventHandler ColorChangedEvent;
与主题一样,当主题通知观察者(在上方的 Update
方法中)时,将触发 ColorChangedEvent
并调用 ColorEventHander
以传递 _color
字符串进行更新!
在此解决方案中,我想更新 Form3
的背景颜色。因此,此观察者对象将在 form3
中创建,并通过构造函数将 textbox
对象传递给观察者。
private TextBox txt;
public Observer(TextBox _txt)
{
this.ColorChangedEvent += new ColorEventHandler(Observer_ColorChangedEvent);
this.txt = _txt;
}
Observer
对象的完整详细信息在此
public class Observer
{
private delegate void ColorEventHandler(string _color);
private event ColorEventHandler ColorChangedEvent;
private TextBox txt;
public Observer(TextBox _txt)
{
this.ColorChangedEvent += new ColorEventHandler(Observer_ColorChangedEvent);
this.txt = _txt;
}
private void OnChange(string _color)
{
if (ColorChangedEvent != null)
{
ColorChangedEvent(_color);
}
}
public void Update(string _color)
{
OnChange(_color);
}
private void Observer_ColorChangedEvent(string _color)
{
switch (_color)
{
case "RED":
txt.BackColor = Color.Red;
break;
case "BLUE":
txt.BackColor = Color.Blue;
break;
case "GREEN":
txt.BackColor = Color.Green;
break;
default:
txt.BackColor = Color.Gray;
break;
}
}
}
Form2
当单选按钮被选中时,它会发生变化!它将调用 Subject
对象来更新其客户端。
private void rdRed_CheckedChanged(object sender, EventArgs e)
{
if (rdRed.Checked)
{
objSub.UpdateClient("RED");
lblText.ForeColor = Color.Red;
}
}
private void rdGreen_CheckedChanged(object sender, EventArgs e)
{
if (rdGreen.Checked)
{
objSub.UpdateClient("GREEN");
lblText.ForeColor = Color.Green;
}
}
private void rdBlue_CheckedChanged(object sender, EventArgs e)
{
if (rdBlue.Checked)
{
objSub.UpdateClient("BLUE");
lblText.ForeColor = Color.Blue;
}
}
当您单击 Button 创建并打开 Form3
时,窗体中有一个名为 objSub
的主题对象,它通过构造函数传递到 form3
。
private Subject objSub;
private Form3 frm;
public Form2()
{
InitializeComponent();
objSub = new Subject();
}
private void btnOpen_Click(object sender, EventArgs e)
{
frm = new Form3(objSub);
frm.Show();
}
Form3
只需创建一个新的 Observer 对象并将其注册到 objSub
。
public Form3(Subject _objSub)
{
InitializeComponent();
objSub = _objSub;
obs = new Observer(this.textBox1);
objSub.RegisterClient(obs);
}
就是这样!当您单击单选按钮时,它将调用主题来更新其 arraylist
中的客户端。客户端将收到通知,并通过主题传递的颜色更新 textbox
的背景。
关注点
用一个简单的例子来实现观察者模式非常紧凑!希望您能理解并从这个小例子中学习如何解决您的问题!
随时与我联系!
姓名:Nguyen Anh Vu(先生)
电子邮件:vuna209@gmail.com
手机:+84984886940
地址:7 楼, 53 Quang Trung, 河内, 越南。