zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式(Observer)

    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)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者
    知道所观察的对象是怎么发生变化的。

  • 相关阅读:
    JS魔法堂:阻止元素被选中
    JS魔法堂之实战:纯前端的图片预览
    CentOS6.5菜鸟之旅:纯转载Linux目录结构
    Vim杂记:Sublime的配色方案
    Vim杂记:markdown插件
    CentOS6.5菜鸟之旅:中文编辑器忍痛放弃Sublime
    JS魔法堂:Data URI Scheme介绍
    CentOS6.5菜鸟之旅:安装ATI显卡驱动
    JS魔法堂:获取当前脚本文件的绝对路径
    腊八蒜
  • 原文地址:https://www.cnblogs.com/gylhaut/p/5793195.html
Copyright © 2011-2022 走看看