观察者模式:
定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自己更新自己。
观察者结构模式图:
结合例子:
static void Main(string[] args) { //老板dandan Boss dandan=new Boss (); //看股票的同事 StockObserver hongjie=new StockObserver ("张三",dandan ); dandan.Attach (hongjie ); //老板回来 dandan .SubjectState="丹丹回来了"; //发出通知 dandan.Notify (); } //通知者接口 interface Subject { void Attach(Observer observer); void Detach(Observer observer); void Notify(); string SubjectState { get; set; } } //具体通知者类 class Boss:Subject { //同事列表 private IList<Observer > observers=new List<Observer>(); private string action; //增加 public void Attach(Observer observer) { observers.Add (observer ); } //减少 public void Detach(Observer observer) { observers.Remove (observer ); } //通知 public void Notify() { foreach (Observer o in observers ) o.Update (); } //老板状态 public string SubjectState { get {return action ;} set {action =value ;} } } //抽象观察者 abstract class Observer { protected string name; protected Subject sub; public Observer (string name,Subject sub) { this.name =name ; this.sub =sub ; } public abstract void Update(); } class StockObserver:Observer { public StockObserver (string name,Subject sub):base(name,sub ) { } public override void Update() { Console .WriteLine ("{0}{1}关闭股票行情,继续工作!",sub.SubjectState ,name ); } }这里用到了一个接口Subject和一个抽象类Observer,这两个抽象类的使用体现了面向对象的思想,减少了观察者与被观察者之间的耦合度,如果我们直接写出公司中的boss(被观察者)和observer(观察者),那么他们之间必然会有紧密的联系,如果被观察者改变或增加,不管被观察者类会受到影响,由于被观察者与观察者之间的紧耦合,则,观察者也必然会做相应修改,这不符合依赖倒转原则和开闭原则。因此,我们需要用观察者模式,一方面,观察者模式具有一个对象的改变可以同时改变其他所有对象;另一方面,观察者模式运用接口和抽象类,降低了耦合度,符合设计原则,增强了程序的可维护、扩展和重用性。
但这一设计模式仍然有其缺点,因为这种模式的一个特点是抽象通知类还是依赖抽象观察类的,如果没有抽象观察类,那么通知就无法实现,所以为了避免这一不足,我们就用到了委托事件。
事件委托与观察者模式:
在之前的博客中,我已经讲到了委托,何谓委托?简单的说委托可以看做是对函数的抽象,是函数的类,委托的实例将代表一个实例,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。在没有抽像观察类的情况下,我们可以通过使用事件委托,将同一通知发给所有通知者,即时没有接口,这一功能同样可以实现,而且降低了与抽象通知类之间的依赖关系,增加了扩展性、灵活性。
观察者模式的几个要点:
1、使用面向对象的抽象,观察者模式使得我们可以独立改变目标与观察者,从而使得两者之间的依赖关系达到松耦合
2、目标发送通知时,无需指定观察者,通知会自动传播。观察者自己决定是否需要订阅通知,目标对象对此一无所知。
3、委托充当了抽象的观察者接口,而提供事件的对象充当饿了目标对象。委托是比抽象观察者接口更为松耦合的设计。