说明 :观察者模式又叫发布-订阅模式,其中又涉及到中介者模式
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 } }