设计模式之观察者模式与事件委托

1、观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

说简单点就是一个事物由于某个因素的变化而去提醒别的事物,让它们做出相应的改变。就像是猫叫了,老鼠跑了,人醒了。因素是猫叫,而猫这个实体去提醒老鼠和人,做出的反映分别是老鼠跑了,人醒了。代码如下:


//抽象类观察者
abstractclass  Obverser
{
	//抽象类初始化,引用接口Subject
	protected Subject sub;
	public Obverser(Subject sub)
	{
		this.sub=sub;
	}
 
	//定义抽象方法Respond()
	 public  abstract Void Respond();
}
 
//类Mouse,继承抽象类Obverser
classMouse :Obverser
{
	//Mouse类的初始化
	public Mouse(Subject sub):base(sub)
	{}
 
	//类Mouse中方法Respond()的重写
	public override void Respond()
	{
		Console.WriteLine("{0} 老鼠跑了",sub.SubjectState);
	}
}
 
//类People,继承抽象类Obverser
classPeople :Obverser
{
	//People类的初始化
	public People(Subject sub):base(sub)
	{}
 
	//类People中方法Respond()的重写
	public override void Respond()
	{
		console.WriteLine("{0} 人醒了",sub.SubjectState);
	}
}
 
//定义公共接口
Interface  Subject
{
	//接口中的公共方法,属性
	void Attach(Obverser obverser);
	void Detach(Obverser obverser);
	string SubjectState
	{
		get;
		set;
	}
}
 
//类Cat继承接口Subject,实现其方法
classCat:Subject
{
	//定义数组obversers,存放类Obverser变量
	private Ilist<Obverser> obversers=new List<Obverser>();
	private string action;
 
	//实现接口方法Attach,增加数组个数
	public void Attach(Obverser obverser)
	{
		obversers.Add(obverser);
	}
	//实现接口方法Attach,减少数组个数
	public void Detach(Obverser obverser)
	{
		obversers.Remove(obverser);
	}
 
	//私有变量action的读取
	public string SubjectState
	{
		get{return action;}
		set {action=value;}
	}
 
	//方法Notify(),提醒老鼠和人引发他们的改变
	public void Notify()
	{
		foreach (Obverser o in obversers)
		o.Respond();
	}
}

主函数中则如下:


Cat cat=new Cat();              //实例化Cat类
Mouse mouse=new Mouse(cat);     //实例化Mouse类
People people=new People(cat);  //实例化People类
 
Cat.Attach(mouse);              //增加数组变量
Cat.Attach(people);             //减少数组变量
 
Cat.SubjectState="猫叫了";      //猫的行为
Cat.Notify();                   //引发的老鼠和人的反应

通过上面的例子可以知道什么是观察者模式,但是同样的其也有其不可避免的缺点,现实编程中,具体的观察者完全是风马牛不相及的类,但是他们都需要根据通知者的通知做出反应。比如上面的类将MousePeople类中的方法Respond()分别改成RespondOfPeople()RespondOfMouse();都做出了反映,但是做出反映的方法不同。为解决这类问题而特意提出的事件委托。

 

2、委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。

一个委托可以搭载多个方法,所有方法被一次唤起。它可以使委托对象搭载的方法并不需要属于同一个类。但是委托也有前提:委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型。

还拿上面的例子来说:


classPeople :Obverser
{
	//People类的初始化,引用接口Subject
	protected Subject sub;
	public Obverser(Subject sub)
	{
		this.sub=sub;
	}
 
	//类People中方法Respond()的重写
	public override void RespondOfPeople()
	{
		console.WriteLine("{0} 人醒了",sub.SubjectState);
	}
}
ClassMouse
{
	//Mouse类和People类类似,这里不再重复。
}
 
//声明一个委托,名称叫“EventHandler(事件处理程序)”
delegate void EventHandler;
 
//类Cat继承接口Subject,实现其方法
classCat:Subject
{
	//声明一件事Update,类型为委托EventHandler
	public event EventHandler Update;
	private string action;
 
	//私有变量action的读取
	public string SubjectState
	{
		get{return action;}
		set {action=value;}
	}
 
	//方法Notify(),提醒老鼠和人引发他们的改变
	public void Notify()
	{
		Update();
	}
}

客户端代码如下:

Catcat=new Cat();
Peoplepeople=new People(cat);
Mousemouse=new Mouse(cat);
 
cat.Update+=newEventHandler(people.RespondOfPeople);
cat.Update+=newEventHandler(mouse.RespondOfMouse);
 
cat.SubjectState="猫叫"
cat.Notify();

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值