观察者(Observer)模式

1. 观察者模式介绍

       观察者模式是对象行为模式,又叫做发布-定义模式、模型-视图模式、源-监听器模式或从属者模式。

 

       观察者模式定会以了一种一对多的依赖关系,让多个观察者同事监听一个主题对象,这个主题在状态发生变化是,会通知所有观察者对象,使他们能够自动跟新自己。

 

2.观察者模式的结构

 

l         抽象主题(Subject)角色:主题角色把所有对观察者对象的引用保存在一个聚集(List)中,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察着角色,一般用一个抽象类或者一个接口实现

 

l         抽象观察者(Observer)角色:为所有具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口又叫做更新借口。抽象观察者角色一般用一个抽象类或一个接口实现。

 

l         具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体的主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察着角色。

 

       具体观察者(ConcreteObserver)角色:存储于主题状态自恰的状态。具体观察者角色实现抽象观察者角色所要求更新接口,以便使本身的状态与主题的状态相协调

 

3. 使用观察者模式关闭winform颜色

Winform使用观察者模式改变窗体背景颜色,效果图如下:

 

 

 

点击窗体1、窗体2,将显示窗体1和窗体2,点击红色、蓝色,窗体1和窗体2同事改变相应的颜色,如同系统皮肤实现。

以下是具体的实现:

1.       创建观察者:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObserverForm
{
/// <summary>
/// 观察者接口
/// </summary>
public interface IObserver
{
void changeColor(string
}
}

 

 

2.       创建抽象主题:Iobservable.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObserverForm
{
/// <summary>
/// 主题接口
/// </summary>
public interface IObservable
{
void add(IObserver
void remove(IObserver
void change(string
}
}

这个抽象接口定义了3个方法子类必须实现的操作,add()用来添加一个观察者对象,remove用来删除一个已经登记过的观察者对象;而change()用来通知各个观察者更新他们自己。

       现在抽象主题、抽象观察者都已存在,剩下就该创建具体主题和具体观察者了。具体主题实现了抽象主题Iobservable接口的一个类,他给出了以上的三种方法的具体实现,如下,创建一个Form实现MainForm.cs实现Iobserverable.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ObserverForm
{
/// <summary>
/// 主题form
/// </summary>
public partial class MainForm : Form,IObservable
{
private List<IObserver> observersList = new List<IObserver>();

public
{
InitializeComponent();
}

public void add(IObserver
{
observersList.Add(o);
}

public void remove(IObserver
{
observersList.Remove(o);
}

public void change(string
{
foreach (IObserver o in
{
o.changeColor(color);
}
}

private void button1_Click(object sender, EventArgs
{
Form1 f1 = new Form1();
observersList.Add(f1);
f1.Show();
}

private void button2_Click(object sender, EventArgs
{
Form2 f2 = new Form2();
observersList.Add(f2);
f2.Show();
}

private void button3_Click(object sender, EventArgs
{
this.change("红色");
}

private void button4_Click(object sender, EventArgs
{
this.change("绿色");
}

 

抽象观察者的具体实现最为简单,在此处只需实现一个方法,在此例子中有两个观察者他们只需实现此接口即可。具体实现如下:

观察者1

/// <summary>
/// 观察者form1
/// </summary>
public partial class Form1 : Form,IObserver
{
public
{
InitializeComponent();
}

public void changeColor(string
{
if(str == "红色")
this.BackColor = Color.Red;
if (str == "绿色")
this.BackColor = Color.Blue;
}
}

 

观察者2:

/// <summary>
/// 观察者form2
/// </summary>
public partial class Form2 : Form,IObserver
{
public
{
InitializeComponent();
}

public void changeColor(string
{
if (str == "红色")
this.BackColor = Color.Red;
if (str == "绿色")
this.BackColor = Color.Blue;
}
}

 

 

4.使用事件与委托改进观察者模式改变窗体winform颜色:

       在C#中,确切的说事在.Net框架中,关于事件与委托的处理采用了观察者模式。由于委托与接口的差别,利用事件与委托在解耦性方面具有一定的优势。以下将引入事件与委托机制对上面进行改进:

/// <summary>
/// 观察者
/// </summary>
/// <param name="color"></param>
public delegate void ChangeCorlorHandler(string);
/// <summary>
/// 主题
/// </summary>
public class Subject
{
public static event ChangeCorlorHandler

public static void ChangeColor(String
{
if (eventChanageColor != null)
eventChanageColor(color);
}
}

 

/// <summary>
/// 主题form
/// </summary>
public partial class MainForm : Form
{
public
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs
{
Form1 f1 = new Form1();
f1.Show();
}

private void button2_Click(object sender, EventArgs
{
Form2 f2 = new Form2();
f2.Show();
}

private void button3_Click(object sender, EventArgs
{
Subject.ChangeColor("红色");
}

private void button4_Click(object sender, EventArgs
{
Subject.ChangeColor("绿色");
}
}

 

    /// <summary>

    /// 观察者form1

    /// </summary>

    public partial class Form1 : Form

    {

        public

        {

            InitializeComponent();

            Subject.eventChanageColor += new ChangeCorlorHandler(ChangeColor);

        }

 

        public void ChangeColor(string

        {

            if(str == "红色")

                this.BackColor = Color.Red;

            if (str == "绿色")

                this.BackColor = Color.Blue;

        }

 

    }

 

/// <summary>
/// 观察者form2
/// </summary>
public partial class Form2 : Form
{
public
{
InitializeComponent();
Subject.eventChanageColor += new ChangeCorlorHandler(ChangeColor);
}

public void ChangeColor(string
{
if (str == "红色")
this.BackColor = Color.Red;
if (str == "绿色")
this.BackColor = Color.Blue;
}
}