模式二:观察者模式

      2.1观察者模式定义:

观察者模式定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

 

2.2观察者模式UML类图:

一个观察者只有一个主题

一个主题对应多个观察者

<<Interface>>

Subject

 

RegisterObserver()

RemoveObserver()

NotifyObservers()

ConcreteSubject

 

RegisterObserver(){…}

RemoveObserver(){…}

NotifyObservers(){…}

<<Interface>>

Observer

 

Update()

ConcreteObserver

 

 

Update(){…}

 

一个观察者只有一个主题

一个主题对应多个观察者

<<Interface>>

Subject

 

RegisterObserver()

RemoveObserver()

NotifyObservers()

ConcreteSubject

 

RegisterObserver(){…}

RemoveObserver(){…}

NotifyObservers(){…}

<<Interface>>

Observer

 

Update()

ConcreteObserver

 

 

Update(){…}

一个观察者只有一个主题

一个主题对应多个观察者

<<Interface>>

Subject

 

RegisterObserver()

RemoveObserver()

NotifyObservers()

ConcreteSubject

 

RegisterObserver(){…}

RemoveObserver(){…}

NotifyObservers(){…}

<<Interface>>

Observer

 

Update()

ConcreteObserver

 

 

Update(){…}

2.3应用场景

       现实世界中的报纸和订阅者之间的模式是一个最好的观察者模式。我们的报刊(Subject)一有更新就会发通知(送报纸)给所有报刊订阅人(Observers)。

 

2.4观察者模式分析与实现(c#描述)

 

//主题接口

    public interface ISubject

    {

        void RegisterObserver(IObserver observer);

        void RemoveObserver(IObserver observer);

        void NotifyObservers();

    }

 

    //观察者接口

    public interface IObserver

    {

        void Update(string astg_MsgFromSubject);

    }

 

    //主题实现类

    public class Subject : ISubject

    {

        private ArrayList ial_Observers = new ArrayList();

        private string _SubjectInfo;//主题更新信息

 

        public string SubjectInfo

        {

            get { return _SubjectInfo; }

            set {

                _SubjectInfo = value;

                this.NotifyObservers();//通知观察者

            }

        }      

       

        public void RegisterObserver(IObserver observer)

        {

            if (this.ial_Observers.IndexOf(observer) < 0)

            {

                this.ial_Observers.Add(observer);           

            }           

        }

 

        public void RemoveObserver(IObserver observer)

        {

            if (this.ial_Observers.IndexOf(observer) > -1)

            {

                this.ial_Observers.Remove(observer);

            }

        }

 

        public void NotifyObservers()

        {

            for (int lint_LoopCount = 0; lint_LoopCount < this.ial_Observers.Count; lint_LoopCount++)

            {

                ((IObserver)this.ial_Observers[lint_LoopCount]).Update(this.SubjectInfo);

            }

        }       

 

    }

 

    //观察者实现类

    public class Observer : IObserver

    {

        private string istg_Info;

        public Observer(string astg_Info)

        {

            this.istg_Info = astg_Info;

        }

 

        public void Update(string astg_MsgFromObject)

        {

            Console.WriteLine("更新观察者:" + this.istg_Info + " 这是来自主题的消息:" + astg_MsgFromObject);

        }

   

    }

 

    //调用类

    public class Subject_Observers_Test

    {

        public static void Do()

        {

            Subject lobj_Subject = new Subject();   

       

            //注册观察者1

            IObserver lobj_Observer1 = new Observer("1");

            lobj_Subject.RegisterObserver(lobj_Observer1);

 

            //注册观察者2

            Observer lobj_Observer2 = new Observer("2");

            lobj_Subject.RegisterObserver(lobj_Observer2);

 

            //通知观察者           

            lobj_Subject.SubjectInfo = "今天是星期天。";

 

            //撤消观察者1

            lobj_Subject.RemoveObserver(lobj_Observer1);

 

            //再次通知观察者

            lobj_Subject.SubjectInfo = "现在是下午3点钟。";

          

        }

   

    }

      至此,观察者模式完毕。

 

观察者模式体现了上述的面向对象设计的几个原则,下面重点强调一下其中之一:为交互对象之间的松耦合设计而努力

 

交互对象这里对应的就是主题和观察者。之所以说主题和观察者之间的关系是松耦合的,这是因为:关于观察者的一切,主题只知道观察者实现了某一个接口,主题依赖的是观察者的接口,而不是具体的观察者实现。另外,由于是观察者实现了接口,则程序运行的任何时候,我们都可以动态的增减观察者(前提是必须有指向当前主题对象的引用,则可以为该主题对象动态的增减观察者),而主题代码不需要作任何变动,而不是在编译之前就决定了只能通知哪些观察者。改变主题和观察者之间的任何一方,互相对对方不造成任何影响,这就是主题和观察者之间的松耦合关系。

 

   同样,观察者模式也有其不是令人非常满意的地方。观察者模式中观察者获取数据的方式为被动的接受主题的通知,而主题只在全部数据更新后才一次性通知观察者数据要更新了。这样有可能不太方便,因为如果某些观察者只希望要主题的一部分数据,就没有必要被动等主题通知才获得数据,则想要产生一种主动提要求获得数据的方法。前者称之为推模式,后者称之为拉模式。这两种模式各有各的好处,但后者需要将主题数据暴露给观察者,这种方式不太好,但仍可根据实际情况具体考虑。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值