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

    观察者模式: 

      

    一、定义:

      观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。此种模式通常被用来实时事件处理系统。其中两个重要对象是观察者和主题,要想主题对象发生改变时,能通知到所有观察者角色,则自然主题角色必须引用观察者,从而完成观察模式。

       特点:

      1、定义了一对多的关系。

      2、主题用一个共同的接口来更新观察者。

      3、观察者和主题用松耦合的方式结合,不需要知道实现细节,只需要实现接口就可以。

    二、UML类图:

      

    三、基本代码:  

    class Program
        {
            static void Main(string[] args)
            {
                ConcreteSubject cs = new ConcreteSubject();
    
                cs.Attach(new ConcreteObserver(cs, "x"));
                cs.Attach(new ConcreteObserver(cs, "y"));
    
                cs.SubjectState = "abc";
                cs.Notify();
    
                Console.Read();
            }
        }
    
        abstract class Subject
        {
            private IList<Observer> observers = new List<Observer>();
    
            public void Attach(Observer observer)
            {
                observers.Add(observer);
            }
    
            public void Detach(Observer observer)
            {
                observers.Remove(observer);
            }
    
            public void Notify()
            {
                foreach (Observer ob in observers)
                {
                    ob.Update();
                }
            }
        }
    
        class ConcreteSubject : Subject
        {
            private string subjectState;
            public string SubjectState
            {
                get { return subjectState; }
                set { subjectState = value; }
            }
        }
    
        abstract class Observer
        {
            public abstract void Update();
        }
    
        class ConcreteObserver : Observer
        {
            private string name;
            private string observerState;
            private ConcreteSubject subject;
            public ConcreteSubject Subject
            {
                get { return subject; }
                set { subject = value; }
            }
    
            public ConcreteObserver(ConcreteSubject subject, string name)
            {
                this.subject = subject;
                this.name = name;
            }
    
            public override void Update()
            {
                observerState = subject.SubjectState;
                Console.WriteLine("观察者{0}的新状态是{1}", name, observerState);
            }  
        }
    View Code

    四、适用场景:

      当一个对象的改变需要同时改变其他对象时,而且不知道具体有多少对象有待改变时,应该考虑使用观察者模式。

      举例说明:

      

      实例代码: 

    interface ISubject
        {
            void Attach(Observer observer);
            void Detach(Observer observer);
            void Notify();
            string SubjectState { get; set; }
        }
    
        class Boss : ISubject
        {
            private IList<Observer> observers = new List<Observer>();
            private string bossAction;
    
            public string SubjectState
            {
                get { return bossAction; }
                set { bossAction = value; }
            }
    
            public void Attach(Observer observer)
            {
                observers.Add(observer);
            }
    
            public void Detach(Observer observer)
            {
                observers.Remove(observer);
            }
    
            public void Notify()
            {
                foreach (Observer ob in observers)
                {
                    ob.Update();
                }
            }
        }
    
        abstract class Observer
        {
            protected string name;
            protected ISubject subject;
    
            public Observer(string name, ISubject subject)
            {
                this.name = name;
                this.subject = subject;
            }
    
            public abstract void Update();
        }
    
        class StockObserver : Observer
        {
            public StockObserver (string name,ISubject subject):base(name,subject )
            {}
    
            public override void Update()
            {
                Console.WriteLine("{0},{1} 关闭股票,继续工作", subject.SubjectState, name);
            }
        }
    
        class NBAObserver : Observer
        {
            public NBAObserver (string name,ISubject subject):base(name,subject)
            {}
    
            public override void Update()
            {
                Console.WriteLine("{0},{1} 关闭NBA,继续工作", subject.SubjectState, name);
            }
        }
    View Code
    Boss boss = new Boss();
                Observer s1 = new StockObserver("张三", boss);
                Observer s2 = new NBAObserver("李四", boss);
                boss.Attach(s1);
                boss.Attach(s2);
                boss.SubjectState = "老板回来了";
                boss.Notify();

    五、观察者模式的缺点及解决方法:

      在具体前台、同事和老板的实例中,使用依赖倒转原则,但是“抽象通知者”还是依赖“抽象观察者”,即如果没有抽象观察者这样的接口,通知功能就完不成。另外就是每个具体观察者,它不一定是“更新”的方法要调用,可能是其他的方法。解决方法:通知者和观察者之间根本互相不知道,由客户端决定通知谁。对于前台的实例,决定使用委托的方式来实现由客户端来决定具体通知谁的功能。

      实例说明:

    interface ISubject
        {
            void Notify();
            string SubjectState { get; set; }
        }
    
        public delegate void DelegateHandler();
    
        class Boss : ISubject
        {
            public event DelegateHandler Update;
    
            public string SubjectState { get; set; }
    
            public void Notify()
            {
                Update();
            }
        }
    
        abstract class Observer
        {
            protected string name;
            protected ISubject subject;
    
            public Observer(string name, ISubject subject)
            {
                this.name = name;
                this.subject = subject;
            }
    
            public abstract void Update();
        }
    
        class StockObserver : Observer
        {
            public StockObserver(string name, ISubject subject)
                : base(name, subject)
            { }
    
            public override void Update()
            {
                Console.WriteLine("{0},{1} 关闭股票,继续工作", subject.SubjectState, name);
            }
        }
    
        class NBAObserver : Observer
        {
            public NBAObserver(string name, ISubject subject)
                : base(name, subject)
            { }
    
            public override void Update()
            {
                Console.WriteLine("{0},{1} 关闭NBA,继续工作", subject.SubjectState, name);
            }
        }
    View Code
    Boss boss = new Boss();
                StockObserver s1 = new StockObserver("张三", boss);
                NBAObserver s2 = new NBAObserver("李四", boss);
    
                boss.Update += new DelegateHandler(s1.Update);
                boss.Update += new DelegateHandler(s2.Update);
                boss.SubjectState = "老板回来了";
                boss.Notify();

    六、总结:

      观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体,从而使各自的变化都不会影响到另一边的变化。

  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/ysyn/p/3698680.html
Copyright © 2011-2022 走看看