观察者设计模式就是消息机制,当被观察者的状态发生改变的时候,观察者作出相应的变化,本质上就是通过被观察者发布消息,观察者订阅消息。
假设被观察者是一只猫(在开发过程中可能是一个按钮等),观察者是3只老鼠,当猫作出状态改变的时候,老鼠也要相应作出变化。此时需要用到的就是消息机制即猫发送消息给老鼠,我要来啦!老鼠收到消息之后作处相应的反应。
消息机制需要用到委托和事件,此处做个委托和事件的简单介绍
委托:相当于是一个函数指针(可以这么理解); 事件:一个拥有特殊签名的委托。说的这些都是虚的,直接举个栗子就清楚了。
1 public delegate void aDelegate(); 2 3 public aDelegate aDelegates; 4 5 public event aDelegate aDelegateEvnent;
第一句就是声明一个委托类型,委托其实是个类型;第二句的是声明了一个 aDelegate 类型的委托变量;第三句是声明了一个 aDelegate 类型的事件
委托和事件的区别:事件其实是一个特殊的委托,本质上是一样的,但是在用法上略有区别:委托可以在类的外部直接调用,而事件不可以。这就导致事件相对安全(虽然委托可以在类的外部调用,但是最好别用,容易出错),委托和事件都可以通过 += 对方法进行注册,通过 -= 对方法进行注销。
例子观看结果:
一、现在创建一个被观察者类(Cat):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 设计模式 8 { 9 class Cat 10 { 11 private string name; 12 private string color; 13 14 public Cat(string name,string color) 15 { 16 this.name = name; 17 this.color = color; 18 } 19 20 public void CatComming() 21 { 22 Console.WriteLine(color + "的 " + name + "猫来啦!"); 23 CatComeEvent?.Invoke(); 24 } 25 26 public delegate void CatComeHandler(); 27 public event CatComeHandler CatComeEvent; 28 public CatComeHandler catComeHandler; 29 } 30 }
二、创建一个观察者类(Mouse):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 设计模式 8 { 9 class Mouse 10 { 11 private string name; 12 private string color; 13 14 public Mouse(string name,string color) 15 { 16 this.name = name; 17 this.color = color; 18 } 19 20 public void MouseRun() 21 { 22 Console.WriteLine(name + "说:" + "大猫来了,大家快跑"); 23 } 24 } 25 }
这两个类,只做一件事,就是当 Cat 类调用 CatComming 方法的时候,Mouse 要调用 MouseRun 方法,也就是说,当猫来了,老鼠就要跑,所以也就是被观察者出现状态变化,那么观察者也要作出相应的变化。
在 Cat 类中,分别声明了一个委托和一个事件 CatComeHandler (),CatComeEvent
现在需要做的就是将 Mouse 类中的 MouseRun 方法注册进 CatComeEvent 事件中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 设计模式 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Cat cat = new Cat("Tom", "蓝色"); 14 15 Mouse mouse1 = new Mouse("jackey", "黄色"); 16 17 Mouse mouse2 = new Mouse("bili", "红色"); 18 Mouse mouse3 = new Mouse("pili", "绿色"); 19 20 Mouse mouse4 = new Mouse("cili", "粉色"); 21 22 cat.CatComeEvent += mouse1.MouseRun; 23 cat.CatComeEvent += mouse2.MouseRun; 24 cat.CatComeEvent += mouse3.MouseRun; 25 cat.CatComeEvent += new Cat.CatComeHandler(mouse4.MouseRun); 26 // cat.catComeHandler(); 27 cat.CatComming(); 28 Console.ReadKey(); 29 } 30 } 31 }
咱们将 mouse1,mouse2,mouse3,mouse4 分别注册进了 CatComeEvent 事件中,注册的方式是也通过 += 进行赋值,这个过程通常称为事件的注册或者订阅。
当 Cat 类 调用CatComming() 的时候,就会通知 mouse1,mouse2,mouse3,mouse4,猫已经发生变化,你们赶紧跑吧!