1.观察者模式定义
观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式
、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
2.观察者实例
namespace ObserverDemo { public interface IObserver { void Update(); } } namespace ObserverDemo { public class ConcreteObserver : IObserver { // Fields private string name; private ConcreteSubject subject; private ConcreteSubjectEvent subjectEvent; public ConcreteSubject Subject { get { return subject; } set { subject = value; } } // Constructors public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } public ConcreteObserver(ConcreteSubjectEvent subject, string name) { this.subjectEvent = subject; this.name = name; } public string Name { get { return name; } set { name = value; } } private string observerState; public string ObserverState { get { return observerState; } set { observerState = value; } } public void Update() { observerState = subjectEvent.SubjectState; Console.WriteLine("Observer {0}'s new state is {1}", name, observerState); } } } //1.采用事件实现方式 namespace ObserverDemo { //Delegate public delegate void UpdateDelegate(); //SubjectEvent public class SubjectEvent { public event UpdateDelegate updateHandler; //Methods public void Attach(UpdateDelegate up) { updateHandler += up; } public void Detach(UpdateDelegate ud) { updateHandler -= ud; } public void Notify() { if (updateHandler != null) updateHandler(); } } public class ConcreteSubjectEvent: SubjectEvent { // Fields private string subjectState; // Properties public string SubjectState { get { return subjectState; } set { subjectState = value; } } } } //一般实现方式 namespace ObserverDemo { //Subject public abstract class Subject { //Fields 使用泛型 private List<IObserver> observers = new List<IObserver>(); //Methods public void Attach(IObserver observer) { observers.Add(observer); } public void Detach(IObserver observer){ observers.Remove(observer); } public void Notify() { foreach( IObserver o in observers ) o.Update(); } } public class ConcreteSubject: Subject { // Fields private string subjectState; // Properties public string SubjectState { get { return subjectState; } set { subjectState = value; } } } } namespace ObserverDemo { class Program { static void Main(string[] args) { ConcreteSubjectEvent s = new ConcreteSubjectEvent(); ConcreteObserver o1 = new ConcreteObserver(s, "1"); ConcreteObserver o2 = new ConcreteObserver(s, "2"); s.Attach(new UpdateDelegate(o1.Update)); s.Attach(new UpdateDelegate(o2.Update)); s.SubjectState = "abc"; s.Notify(); Console.Read(); } } }
3.观察者模式在MVVM框架中的应用
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ObserverTest { class Program { static void Main(string[] args) { User user = new User(); View view = new View(user); user.Name = "Java"; Console.Read(); } } public delegate void OnNameChange(string name); public class View { public View(User user) { user.OnNameChanged += user_OnNameChanged; } void user_OnNameChanged(string name) { Console.WriteLine(name); } } public class User { public event OnNameChange OnNameChanged; private string name; public string Name { get{ return Name; } set { name = value; if (OnNameChanged != null) { OnNameChanged(name); } } } } }
4.观察者模式优缺点
优点:
(1)观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,
每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个
共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(2)观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
缺点:
(1)如果一个被观察者(主题)对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式
、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
(2)如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用
观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者
知道所观察的对象是怎么发生变化的。