C# - 设计模式 - 观察者模式

2021-04-21 02:25

阅读:359

观察者模式

问题场景

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

总结模式

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

示例代码

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 ListIObserver> observeList;

        public Publisher( )
        {
            observeList = new ListIObserver>( );
        }

        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( );
        }
    }
}

 

  

 


评论


亲,登录后才可以留言!