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(); //引发的老鼠和人的反应
通过上面的例子可以知道什么是观察者模式,但是同样的其也有其不可避免的缺点,现实编程中,具体的观察者完全是风马牛不相及的类,但是他们都需要根据通知者的通知做出反应。比如上面的类将Mouse和People类中的方法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();