zoukankan      html  css  js  c++  java
  • C#

    观察者模式

    问题场景

    当一个类内部的数据出现某些变化的时候,其它类很感兴趣,它们想要即时得到那个类内部的数据发生变化时的通知。

    总结模式

    把那些对某一特定类型感兴趣的类型称为观察者,把特定类型称为发布者,观察者通过将自身封装成接口类型并注册到特定类型的接口列表中,当特定类型发生变化时,可通过遍历的形式去通知订阅者做出响应。

    示例代码

    namespace AppCUI
    {
        //观察者接口
        public interface IObserver
        {
            //感兴趣的对象发生变化时我用Response做出响应
            void Response( );
        }

        //发布者接口
        public interface IPublish
        {
            void Register( IObserver observer ); //暴露此方法让观察者订阅我发布的主题
            void Remove( IObserver observer ); //暴露此方法让观察者注销我发布的主题
            void DataChange( ); //发布主题后通知观察者
        }

        //发布者
        public class Publisher : IPublish
        {
            private List<IObserver> observeList;

            public Publisher( )
            {
                observeList = new List<IObserver>( );
            }

            public void Register( IObserver observer )
            {
                observeList.Add( observer );
            }

            public void Remove( IObserver observer )
            {
                int index = observeList.IndexOf( observer );
                if (index == -1) return;
                observeList.RemoveAt( index );
            }

            public void DataChange( )
            {
                //为了便于理解,此处假装修改了Publisher的某个字段的值,导致DataChange被调用
                //所以需要通知观察者做出响应
                foreach (var observer in observeList)
                {
                    observer.Response( );
                }
            }
        }

        //观察者
        public class Person : IObserver
        {
            public void Response( )
            {
                Console.WriteLine( "我是Person,我知道你内部发生了变化,谢谢通知" );
            }
        }

        //观察者2
        public class Employee : IObserver
        {
            public void Response( )
            {
                Console.WriteLine( "我是Employee,我知道你内部发生了变化,谢谢通知" );
            }
        }

        public class Programe
        {
            static void Main( string[] args )
            {
                Publisher publisher = new Publisher( );
                Person person = new Person( );
                Employee employee = new Employee( );
                publisher.Register( person );
                publisher.Register( employee );
                //发布者发布了观察者感兴趣的主题
                publisher.DataChange( );
            }
        }
    }

    在C#中,已经有一个很好的解决思路,就是利用事件委托来实现这个发布-订阅的观察者模式。

    namespace AppCUI
    {
        //发布者
        public class Publisher
        {
            public event EventHandler Proxy;

            public void DataChange( )
            {
                //为了便于理解,此处假装修改了Publisher的某个字段的值,导致DataChange被调用
                //所以需要通知观察者做出响应
                Proxy.Invoke( this, null );
            }
        }

        //观察者
        public class Person
        {
            public void Response( object sourceObject, EventArgs args )
            {
                Console.WriteLine( "我是Person,我知道你内部发生了变化,谢谢通知" );
            }
        }

        //观察者2
        public class Employee
        {
            public void Response( object sourceObject, EventArgs args )
            {
                Console.WriteLine( "我是Employee,我知道你内部发生了变化,谢谢通知" );
            }
        }

        public class Programe
        {
            static void Main( string[] args )
            {
                Publisher publisher = new Publisher( );
                Person person = new Person( );
                Employee employee = new Employee( );
                publisher.Proxy += person.Response;
                publisher.Proxy += employee.Response;
                //发布者发布了观察者感兴趣的主题
                publisher.DataChange( );
            }
        }
    }

     

      

    C# - 设计模式目录

  • 相关阅读:
    Vue + Element 中的时间自定义选择框的数据传参绑定分析与js格式化时间参数
    vue 给data 数据的重新初始化
    Vue + Element 后台项目与后台的数据对接
    js将两组数据存到你定义的空的对象数组
    Element ui 自定义表格行样式
    vue组件的注册与使用
    Vue + Element 实现下拉选择统计时间数据栏并展示
    Vue + Element后台项目报错(This relative module was not found)
    Echart图的使用技巧,配置相关样式与属性
    7种方法实现数组去重
  • 原文地址:https://www.cnblogs.com/myrocknroll/p/8596772.html
Copyright © 2011-2022 走看看