内容:【使用频率:★★★★★】
1、定义:
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
理解:所谓观察者也就是你以及你的同事观察到了某个对象状态的改变,然后你和你的同事相应的发生了什么行为。例如:老板来了,看NBA的同事把NBA视频关了;玩游戏的同事,把手机锁屏了。
2、图:
Subject类(主题或抽象通知者或目标):被观察的对象。可以是接口也可以是抽象类。每个主题都可以有任何数量的观察者,抽象主题提供一个接口,可以增加删除观察者对象。
ConcreteSubject(具体目标):他是主题或者目标的子类,将有关状态存入具体观察者对象;在具体主题或目标内部状态改变时,给所有登记过的观察者发出通知。例如:老板。
Observer(观察者):为具体的观察者定义一个接口,在得到主题的通知时,更新自己。抽象观察者用一个抽象类或一个接口实现。
ConcreteObserver(具体观察者):实现抽象观察者角色所要求的更新接口,以便本身状态与主题的状态相协调。例如:看NBA的同事,玩游戏的同事
3、代码展示:
class Program
{
static void Main(string[] args)
{
Boss huhansan = new Boss();
//看股票的同事
StockObserver tongshi1 = new StockObserver("weiguanzhai", huhansan);
//看NBA的同事
NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);
huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);
huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);
//老板回来
huhansan.SubjectState = "我胡汉三回来了!";
//发出通知
huhansan.Notify();
Console.Read();
}
}
//通知者接口
interface Subject
{
void Notify(); //通知
string SubjectState //状态
{
get;
set;
}
}
//事件处理程序的委托
delegate void EventHandler();
//前台秘书
class Secretary : Subject
{
public event EventHandler Update;//声明一事件Update,类型为委托EventHandler
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value;}
}
}
//老板
class Boss : Subject
{
//声明一事件Update,类型为委托EventHandler
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//看股票的同事
class StockObserver
{
private string name;
private Subject sub;//声明一个通知者,类型为Subject
public StockObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
//关闭股票行情
public void CloseStockMarket()
{
Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
//看NBA的同事
class NBAObserver
{
private string name;
private Subject sub;
public NBAObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
//关闭NBA直播
public void CloseNBADirectSeeding()
{
Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
运行结果:
4、优点和缺点:
(1)优点:
观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。
满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
(2)缺点:
观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。
5、适用性(什么时候可以用观察者模式):
•当一个抽象模型有两个方面, 一个方面依赖于另一方面,将这二者封装在独立的对象中可以使它们可以各自独立地改变和复用。
•当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
•当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦
6、总结:
委托:就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的'类',委托的实例将代表一个具体的函数。委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型。
观察者模式通过把一对多对象之间的通知依赖关系变得更加松散,减少了耦合性,大大提高了程序的可维护性和可扩展性,符合开放-封闭原则。