观察者(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; } } |