观察者模式【设计模式】

观察者模式【设计模式】

观察者模式【设计模式】

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern.

[1]

 The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits.
观察者模式是一种软件设计模式。在观察者模式中,有一个目标,该目标管理维护一堆对它的状态有依赖的观察者,当目标的状态发生变化时,通知所有观察者,通过调用观察者暴露的方法.观察者模式,通常用来实现事件分发处理系统。

观察者模式是MVC架构的重要组成部分。观察者模式在几乎所有GUI组件的实现中应用。



观察者模式:
1.观察者
2.目标

观察者添加注册到目标中,作为目标的成员变量。
目标的状态发生变化的时候,调用观察者的提供的通知方法,告诉观察者当前目标状态发生变化了。

这就是观察者模式。


看图理解观察者模式的含义:

观察者模式【设计模式】

使用观察者会出现的问题:
 
The observer pattern can cause memory leaks, known as the lapsed listener problem, because in basic implementation it requires both explicit registration and explicit deregistration, as in the dispose pattern, because the subject holds strong references to the observers, keeping them alive. This can be prevented by the subject holding weak references to the observers.
会出现内存泄漏。因为目标持有观察者的强引用,当观察者要被销毁的时候,由于有其它对象持有观察者的引用,那么会导致观察者对象没有被回收。不过,这可以通过,让目标只是持有观察者的弱引用来避免这个问题。

C#:
using System;using System.Collections;
 
namespace Wikipedia.Patterns.Strategy{
        // IObserver --> interface for the observer
        public interface IObserver
        {
                // called by the subject to update the observer of any change
                // The method parameters can be modified to fit certain criteria
                void Update(string message);
        }
 
        public class Subject
        {
                // use array list implementation for collection of observers
                private ArrayList observers;
 
                // constructor
                public Subject()
                {
                        observers = new ArrayList();
                }
 
                public void Register(IObserver observer)
                {
                        // if list does not contain observer, add
                        if (!observers.Contains(observer))
                        {
                                observers.Add(observer);
                        }
                }
 
                public void Deregister(IObserver observer)
                {
                        // if observer is in the list, remove
                        if (observers.Contains(observer))
                        {
                                observers.Remove(observer);
                        }
                }
 
                public void Notify(string message)
                {
                        // call update method for every observer
                        foreach (IObserver observer in observers)
                        {
                                observer.Update(message);
                        }
                }
        }
 
        // Observer1 --> Implements the IObserver
        public class Observer1 : IObserver
        {
                public void Update(string message)
                {
                        Console.WriteLine("Observer1:" + message);
                }
        }
 
        // Observer2 --> Implements the IObserver
        public class Observer2 : IObserver
        {
                public void Update(string message)
                {
                        Console.WriteLine("Observer2:" + message);
                }
        }
 
        // Test class
        public class ObserverTester
        {
                [STAThread]
                public static void Main()
                {
                        Subject mySubject = new Subject();
                        IObserver myObserver1 = new Observer1();
                        IObserver myObserver2 = new Observer2();
 
                        // register observers
                        mySubject.Register(myObserver1);
                        mySubject.Register(myObserver2);
 
                        mySubject.Notify("message 1");
                        mySubject.Notify("message 2");
                }
        }}