简介:
观察者模式的意图是定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
在事件event中,委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。
介绍:
优点 | 1.被观察者和观察者之间建立了一个抽象的耦合,被观察者保存着抽象观察者的集合。 2.支持订阅广播通信。被观察者会向所有注册过得观察者发出通知。 |
缺点 | 1.如果被观察者有很多观察者时,通知时会浪消耗大量的时间。 2.观察者仅仅知道观察目标发生了变化,而不知道怎么变化的。 |
特点 | 1.观察者和被观察者的依赖关系是松耦合。 |
抽象主题角色(Subject) | 抽象主题把所有观察者对象的引用保存在一个集合中,并提供操纵观察者对象的操作。抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。 |
抽象观察者角色(Observer) | 为所有具体观察者定义一个接口,在得到主题通知时更新自己。 |
具体主题角色(ConcreteSubject) | 实现抽象主题角色接口,具体主题角色又叫做具体被观察者角色。 |
具体观察者角色(ConcreteObserver) | 实现抽象观察者角色接口。 |
使用:
本案例的意思是学生考试后的成绩、排名的更新。
//Subject
public abstract class ITeacher
{
protected List<IStudent> list;
public ITeacher()
{
list = new List<IStudent>();
}
public abstract void Add(IStudent s);
public void Notify()
{
foreach (IStudent s in list)
{
if (s.isExam)
{
s.Update();
s.isExam = false;
}
}
}
}
//ConcreteSubject
public sealed class Teacher : ITeacher
{
public override void Add(IStudent s)
{
list.Add(s);
}
}
//Observer
public abstract class IStudent
{
private string _name;
public bool isExam;
public IStudent(string name)
{
_name = name;
}
public void Exam()
{
isExam = true;
//do something
}
public abstract void Update();
}
//ConcreteObserver
public sealed class Student : IStudent
{
public Student(string name) : base(name) { }
public override void Update()
{
//do something
}
}
//观察者模式调用
IStudent s1 = new Student("赵"); //学生
IStudent s2 = new Student("钱");
ITeacher t1 = new Teacher(); //老师
t1.Add(s1);
t1.Add(s2);
s1.Exam(); //考试
s2.Exam();
t1.Notify(); //通知更新分数,排名等等