观察者模式(Observer Pattern)

观察者模式(Observer Pattern)

观察者模式(Observer Pattern)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

别名

依赖(Dependents),发布-订阅(Publish/Subscribe)

结构


参与者
Subject
(目标)
——目标知道它的观察者。可以有任意多个观察者观察同一个目标。
——提供注册和删除观察者对象的接口。
Observer
(观察者)
——为那些在目标发生改变时需获得通知的对象定义一个更新接口。
ConcreteSubject(具体目标)
——将有关状态存入各CreateObserver对象。
——当它的状态发生改变,向它的各个观察者发出通知。
ConcreteObject(具体观察者)
——维护一个指向ConcreteSubject对象的引用。
——存储有关状态,这些状态应与目标的状态保持一致。
——实现Observer的更新接口以使自身状态与目标的状态保持一致。

协作


代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyObserver
{
    class Subject
    {
        IList<Observer> observers = new List<Observer>();

        public void Attach(Observer o)
        {
            observers.Add(o);
        }

        public void Detach(Observer o)
        {
            observers.Remove(o);
        }

        public void Nofity()
        {
            foreach (Observer o in observers)
            {
                o.Update();
            }
        }
    }

    class ConcreteSubject : Subject
    {
        private string subjectState;

        public string SubjectState
        {
            get { return subjectState; }
            set { subjectState = value; }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyObserver
{
    interface Observer
    {
        void Update();
    }

    class ConcreteObserver : Observer
    {
        private string name;
        private string observerState;
        
        // ConcreteSubject对象的引用
        private ConcreteSubject cs; 

        public ConcreteObserver(ConcreteSubject cs, string name)
        {
            this.name = name;
            this.cs = cs;
        }

        public void Update()
        {
            // 获取目标状态,用于自身状态的更新
            observerState = cs.SubjectState;
            Console.WriteLine("观察值{0}的新状态是{1}", name, observerState); 
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyObserver
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteSubject s = new ConcreteSubject();

            s.Attach(new ConcreteObserver(s, "X"));
            s.Attach(new ConcreteObserver(s, "Y"));
            s.Attach(new ConcreteObserver(s, "Z"));

            s.SubjectState = "ABC";
            s.Nofity();

            Console.ReadKey();
        }
    }
}

效果
1) 目标和观察者间的抽象耦合
2)支持广播通信 
3)意外的更新

实现
1) 创建目标到其观察者之间的映射 一个目标对象跟踪它应通知的观察者的最简单的方法是显式地在目标中保存对它们的引用。然而,当目标很多而观察者较少时,这样存储可能代价太高。一个解决办法是用时间换空间,用一个关联查找机制 (例如一个hash表来维护目标到观察者的映射。这样一个没有观察者的目标就不产生存储开销。但另一方面,这一方法增加了访问观察者的开销。
2)谁触发更新 Notify不总是由目标对象调用,它也可被一个观察者或其它对象调用。
3)在发出通知前确保目标的状态自身是一致的。
4)避免特定于观察者的更新协议—推/拉模型(push model/pull model)
5) 显式地指定感兴趣的改变 你可以扩展目标的注册接口 ,让各观察者注册为仅对特定事件感兴趣,以提高更新的效率。
void Subject::Attach(Observer*, Aspect& interest);
void Observer::Update(Subject*, Aspect& interest);

All is well!微笑,下期事件与委托



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值