说明 :观察者模式又叫发布-订阅模式,其中又涉及到中介者模式
1 结构
2 创建Main窗体(中介者),ChildForm1(发布者),ChildForm2(订阅者),ChildForm3(订阅者),
2.1 ChildForm1中添加按钮,当按钮被点击是ChildForm2(订阅者),ChildForm3(订阅者),的文本框汇中获取信息
2.2 定义接口
public interface IMessageOn
{
void RecieveMsg(string str);
}
2.3 在发布者ChildForm1中创建MessageOnList集合
2.4 订阅者ChildForm2,ChildForm3中实现接口
public void RecieveMsg(string str)
{
this.txtGetTime.Text = str;
}
2.5 中介者Main把 订阅者放入到发布者的MessageONList集合中
ChildForm2 frm2 = new ChildForm2();
//2把订阅者放入到发布者的MessageONList集合中
frm1.MessageOnList.Add(frm2);
//3显示窗体
frm2.Show();
2.6 遍历集合,通知所有的观察者
foreach (var MessageOn in MessageOnList)
{
MessageOn.RecieveMsg(txtSendMsg.Text);
}


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class Main : Form{public Main(){InitializeComponent();}private void btnOpenForm_Click(object sender, EventArgs e){//1创建窗体ChildForm1 frm1 = new ChildForm1();frm1.Show();ChildForm2 frm2 = new ChildForm2(); //2把订阅者放入到发布者的MessageONList集合中 frm1.MessageOnList.Add(frm2);//3显示窗体 frm2.Show();ChildForm3 frm3 = new ChildForm3();frm1.MessageOnList.Add(frm3);frm3.Show();}} }


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 中介者_订阅者 {public interface IMessageOn{void RecieveMsg(string str);} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm1 : Form{public ChildForm1(){InitializeComponent();MessageOnList = new List<IMessageOn>();}public List<IMessageOn> MessageOnList { set; get; }private void btnSendTime_Click(object sender, EventArgs e){foreach (var MessageOn in MessageOnList){MessageOn.RecieveMsg(txtSendMsg.Text);}}} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm2 : Form,IMessageOn{public ChildForm2(){InitializeComponent();}public void RecieveMsg(string str){this.txtGetTime.Text = str;}} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm3 : Form,IMessageOn{public ChildForm3(){InitializeComponent();}public void RecieveMsg(string str){this.txtGetTime.Text = str;} } }
通过中介者,将发布者和订阅者实现了解耦
3 通过委托实现
3.1 在ChildForm1中声明委托类型
public delegate void SendMsgDel(string sendMsg);
3.2 在ChildForm1中定义委托实例
//02-02定义委托实例
public SendMsgDel SendMsgDelInstance { set; get; }
3.3 在ChildForm2中定义委托实现方法
public void RecieveMsgByDel(string str)
{
this.txtGetTime.Text = str;
}
3.4 Main中将观察者的方法注册到ChildForm1中的委托中去
frm1.SendMsgDelInstance += frm2.RecieveMsgByDel;
3.5 单击按钮触发事件
private void btnDelegate_Click(object sender, EventArgs e)
{
SendMsgDelInstance(txtSendMsg.Text);
}


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class Main : Form{public Main(){InitializeComponent();}private void btnOpenForm_Click(object sender, EventArgs e){//1创建窗体ChildForm1 frm1 = new ChildForm1();frm1.Show();ChildForm2 frm2 = new ChildForm2(); //2把订阅者放入到发布者的MessageONList集合中 frm1.MessageOnList.Add(frm2);frm1.SendMsgDelInstance += frm2.RecieveMsgByDel;//3显示窗体 frm2.Show();ChildForm3 frm3 = new ChildForm3();frm1.MessageOnList.Add(frm3);//2-2将观察者的方法注册到委托中去frm1.SendMsgDelInstance += frm3.RecieveMsgByDel;frm3.Show();}} }


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 中介者_订阅者 {public interface IMessageOn{void RecieveMsg(string str);} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {//02-01定义委托public delegate void SendMsgDel(string sendMsg);public partial class ChildForm1 : Form{public ChildForm1(){InitializeComponent();MessageOnList = new List<IMessageOn>();}#region 01通过发布者模式实现public List<IMessageOn> MessageOnList { set; get; }private void btnSendTime_Click(object sender, EventArgs e){foreach (var MessageOn in MessageOnList){MessageOn.RecieveMsg(txtSendMsg.Text);}} #endregion#region 02通过委托实现//02-02定义委托实例public SendMsgDel SendMsgDelInstance { set; get; }private void btnDelegate_Click(object sender, EventArgs e){SendMsgDelInstance(txtSendMsg.Text);} #endregion} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm2 : Form,IMessageOn{public ChildForm2(){InitializeComponent();}#region 01接口实现发布者模式 方法public void RecieveMsg(string str){this.txtGetTime.Text = str;} #endregion#region 02委托实现方法public void RecieveMsgByDel(string str){this.txtGetTime.Text = str;}#endregion} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm3 : Form,IMessageOn{public ChildForm3(){InitializeComponent();}#region 01接口实现发布者模式 方法public void RecieveMsg(string str){this.txtGetTime.Text = str;}#endregion#region 02委托实现方法public void RecieveMsgByDel(string str){this.txtGetTime.Text = str;}#endregion } }
但是,使用委托有一缺陷==>不安全,
例如,在Main中创建完窗体后直接加一句
frm1.SendMsgDelInstance("委托实现不安全");


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class Main : Form{public Main(){InitializeComponent();}private void btnOpenForm_Click(object sender, EventArgs e){//1创建窗体ChildForm1 frm1 = new ChildForm1();frm1.Show();ChildForm2 frm2 = new ChildForm2(); //2-1把订阅者放入到发布者的MessageONList集合中---接口形式注册 frm1.MessageOnList.Add(frm2);frm1.SendMsgDelInstance += frm2.RecieveMsgByDel;frm1.SendMsgDelEven += frm2.RecieveMsgByEvent;//3显示窗体 frm2.Show();ChildForm3 frm3 = new ChildForm3();frm1.MessageOnList.Add(frm3);//2-2将观察者的方法注册到委托中去----委托形式注册frm1.SendMsgDelInstance += frm3.RecieveMsgByDel;//2-3将观察者的方法注册到事件中去----事件形式注册frm1.SendMsgDelEven += frm3.RecieveMsgByEvent;frm3.Show();frm1.SendMsgDelInstance("委托实现不安全");//frm1.SendMsgDelEven("事件事件安全"); }} }
4通过事件实现


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class Main : Form{public Main(){InitializeComponent();}private void btnOpenForm_Click(object sender, EventArgs e){//1创建窗体ChildForm1 frm1 = new ChildForm1();frm1.Show();ChildForm2 frm2 = new ChildForm2(); //2-1把订阅者放入到发布者的MessageONList集合中---接口形式注册 frm1.MessageOnList.Add(frm2);frm1.SendMsgDelInstance += frm2.RecieveMsgByDel;frm1.SendMsgDelEven += frm2.RecieveMsgByEvent;//3显示窗体 frm2.Show();ChildForm3 frm3 = new ChildForm3();frm1.MessageOnList.Add(frm3);//2-2将观察者的方法注册到委托中去----委托形式注册frm1.SendMsgDelInstance += frm3.RecieveMsgByDel;//2-3将观察者的方法注册到事件中去----事件形式注册frm1.SendMsgDelEven += frm3.RecieveMsgByEvent;frm3.Show();frm1.SendMsgDelInstance("委托实现不安全");//frm1.SendMsgDelEven("事件事件安全"); }} }


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 中介者_订阅者 {public interface IMessageOn{void RecieveMsg(string str);} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {//02-01定义委托public delegate void SendMsgDel(string sendMsg);public partial class ChildForm1 : Form{public ChildForm1(){InitializeComponent();MessageOnList = new List<IMessageOn>();}#region 01通过发布者模式实现public List<IMessageOn> MessageOnList { set; get; }private void btnSendTime_Click(object sender, EventArgs e){foreach (var MessageOn in MessageOnList){MessageOn.RecieveMsg(txtSendMsg.Text);}} #endregion#region 02通过委托实现//02-02定义委托实例public SendMsgDel SendMsgDelInstance { set; get; }private void btnDelegate_Click(object sender, EventArgs e){SendMsgDelInstance(txtSendMsg.Text);} #endregion#region 03事件实现public event SendMsgDel SendMsgDelEven;private void btnEvent_Click(object sender, EventArgs e){if (SendMsgDelEven!=null){SendMsgDelEven(txtSendMsg.Text);}}#endregion} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm2 : Form,IMessageOn{public ChildForm2(){InitializeComponent();}#region 01接口实现发布者模式 方法public void RecieveMsg(string str){this.txtGetTime.Text = str;} #endregion#region 02委托实现方法public void RecieveMsgByDel(string str){this.txtGetTime.Text = str;}#endregion#region 03事件实现方法public void RecieveMsgByEvent(string str){this.txtGetTime.Text = str;}#endregion} }


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 中介者_订阅者 {public partial class ChildForm3 : Form,IMessageOn{public ChildForm3(){InitializeComponent();}#region 01接口实现发布者模式 方法public void RecieveMsg(string str){this.txtGetTime.Text = str;}#endregion#region 02委托实现方法public void RecieveMsgByDel(string str){this.txtGetTime.Text = str;}#endregion#region 03事件实现方法public void RecieveMsgByEvent(string str){this.txtGetTime.Text = str;}#endregion } }