观察者模式

observer

使用思路:订阅者与发布者,发布者改动后通知订阅者。适合一处变动多处响应的场景。

例子

建议先看一下李会军老师的例子

http://www.cnblogs.com/Terrylee/archive/2006/10/23/Observer_Pattern.html

例子包含了观察者代码的演变过程。

以下是本书的例子(C#3.0设计模式)

using System;
using System.Collections;
using System.Threading;
 
class ObserverPattern
{
 
    //Observer Pattern            Judith Bishop Jan 2007
 
    // The Subject runs in a thread and changes its state
    // independently. At each change, it notifies its Observers.
 
    class Subject
    {
        public delegate void Callback(string s);
 
        public event Callback Notify;
 
        Simulator simulator = new Simulator();
        const int speed = 200;
        public string SubjectState { get; set; }
 
        public void Go()
        {
            new Thread(new ThreadStart(Run)).Start();
        }
 
        void Run()
        {
            foreach (string s in simulator)
            {
                Console.WriteLine("Subject: " + s);
                SubjectState = s;
                Notify(s);
                Thread.Sleep(speed); //millisconds
            }
        }
    }
 
    interface IObserver
    {
        void Update(string state);
    }
 
    class Observer : IObserver
    {
        string name;
        Subject subject;
        string state;
        string gap;
 
        public Observer(Subject subject, string name, string gap)
        {
            this.subject = subject;
            this.name = name;
            this.gap = gap;
            subject.Notify += Update;
        }
 
        public void Update(string subjectState)
        {
            state = subjectState;
            Console.WriteLine(gap + name + ": " + state);
        }
    }
 
    static void Main()
    {
        Subject subject = new Subject();
        Observer Observer = new Observer(subject, "Center", "\t\t");
        Observer observer2 = new Observer(subject, "Right", "\t\t\t\t");
        subject.Go();
        Console.ReadKey();
    }
 
    class Simulator : IEnumerable
    {
 
        string[] moves = { "5", "3", "1", "6", "7" };
 
        public IEnumerator GetEnumerator()
        {
            foreach (string element in moves)
                yield return element;
        }
    }
}
/*Output
Subject: 5
    Center: 5
        Right: 5
Subject: 3
    Center: 3
        Right: 3
Subject: 1
    Center: 1
        Right: 1
Subject: 6
    Center: 6
        Right: 6
*/

由李会军老师的代码演变过程得知,Subject与Observer是互相调用的关系。

到本书代码的时候,已经进化为Subject代码内没有任何Observer的影子,仅保留一个事件委托。

如果将 subject.Notify += Update; 脱离出Observer,由客户端来操作的话,则Observer内也完全脱离Subject。真正实现针对接口编程。

原文地址:https://www.cnblogs.com/my36z/p/1557848.html