• 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# - 设计模式目录

  • 相关阅读:
    linux下使用c99链接libuv遇到的问题
    linux连接lua遇到的问题
    uv_timer_t的释放问题
    libuv的源码分析(1)
    [转]关于截取字符串substr和substring两者的区别
    输入框获取焦点后placeholder文字消失、修改placeholder的样式
    发送验证码功能
    针对移动浏览器判断不同的内核的方法
    preventDefault()对象
    [转]JQ中$(window).load和$(document).ready区别与执行顺序
  • 原文地址:https://www.cnblogs.com/myrocknroll/p/8596772.html
Copyright © 2020-2023  润新知