65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.84/5 (21投票s)

2008年9月16日

CPOL

3分钟阅读

viewsIcon

75102

downloadIcon

1789

使用事件和委托在 C# 中实现观察者模式。

pic11.JPG

引言

当您开发应用程序时,我相信您必须处理几个对象。
如果它们需要与同一个源数据交互,我认为您必须找到一种方法来使用数据的更改来更新它们。观察者模式是您可用于此解决方案的关键!

背景

我在该网站上搜索了,发现了一些关于观察者模式的文章。我也阅读了一些关于事件和委托的文章。我想向您——新开发者——展示一种实现观察者模式最简单、最快捷、最易于理解的方式。

现在,让我们开始吧!

Using the Code

我在 Winforms 中创建了一个示例,使用 .NET Framework 2.0 中的 C# 语言。

  • 我有 2 个窗体:Form2Form3
  • form2 中,有 3 个单选按钮、一个 Label 和一个 Button如果您选中单选按钮,您会发现标签的前景色将根据单选按钮的名称更改颜色。这很简单,不是吗?
  • 当您单击按钮打开子窗体时,Form3 将显示!如果您再次选中单选按钮,除了标签的前景色更改外,您还会发现 Form3 中文本框的背景色也将被更改!就是这样!
  • 此解决方案中有 2 个对象
    • Subject(主题):它将是父级!当客户端被创建时,客户端必须向该主题注册。当发生变化时,主题将通知它管理的所有客户端以更新它们。
    • Observer(观察者):它是客户端。当它被创建时,它必须向主题注册,并等待在发生变化时进行更新。

主题对象

首先,我创建一个委托和一个事件,以便在发生变化时使其“活跃”!

private delegate void NotifyHandler(string _color);
private event NotifyHandler NotifyEvent;  

我还创建了一个名为 arrObsArrayList 来管理所有注册到 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);
   }
}

您将看到,当主题被创建时,它将 NotifyEventNotify 方法注册。在 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, 河内, 越南

© . All rights reserved.