日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C#實現觀察者模式(Observer?Pattern)的兩種方式_C#教程

作者:Darren?Ji ? 更新時間: 2022-10-23 編程語言

在觀察者模式中有2個要素:一個是被觀察對象,另一個是觀察者。但被觀察對象的狀態發生改變會通知觀察者。

舉例:把訂閱報紙的人看作是觀察者,把報紙看作被觀察對象。每當有新的新聞就要通知訂閱報紙的人。本篇分別用實現接口和使用委托事件的方式來實現。

通過實現接口實現

觀察者接口,把接收到的新聞顯示出來。

    public interface IObserver
    {
        void Update(string news);
    }

被觀察對象接口,提供3個方法:注冊觀察者,取消觀察者,通知觀察者。

    public interface ISubject
    {
        void RegisteerObserver(IObserver o);
        void RemoveObserver(IObserver o);
        void NotifyObservers();
    }

被觀察對象實現類,維護著一個觀察者接口的集合,對觀察者的注冊和取消實際上是往這個集合添加或移除數據。

    public class NewsPublisher : ISubject
    {
        private List<IObserver>  observers = new List<IObserver>();
        private List<string> newsList = new List<string>(); 
        public void RegisteerObserver(IObserver o)
        {
            observers.Add(o);
        }
        public void RemoveObserver(IObserver o)
        {
            observers.Remove(o);
        }
        public void NotifyObservers()
        {
            foreach (IObserver o in observers)
            {
                o.Update(newsList[newsList.Count - 1]);
            }
        }
        public void PublishNews(string news)
        {
            newsList.Add(news);
            NotifyObservers();
        }
    }

另外,被觀察對象實現類還維護著一個string類型的新聞集合,每當發布新聞,就往這個集合里添加數據,并通知所有的注冊觀察者。

觀察者的實現類。

    public class NewsSubscriber : IObserver
    {
        public void Update(string news)
        {
            Console.WriteLine("收到通知了");
            Console.WriteLine(news);
        }
    }

客戶端,被觀察對象注冊觀察者并觸發動作。

    class Program
    {
        static void Main(string[] args)
        {
            NewsPublisher publisher = new NewsPublisher();
            NewsSubscriber subscriber = new NewsSubscriber();
            publisher.RegisteerObserver(subscriber);
            publisher.PublishNews("看報,看報,快來看報~");
            Console.ReadKey();
        }
    }

使用委托事件實現

看到以上的做法,委托和事件這對好朋友就笑了。注冊、取消觀察者還得用2個方法,那讓我們情何以堪?我們這樣做:

觀察者類只負責對收到的新聞顯示。

    public class NewsSubscriber
    {
        public void Update(string news)
        {
            Console.WriteLine("收到新聞了~");
            Console.WriteLine(news);
        }     
    }

被觀察對象類用到了委托和事件。

    public class NewsPublisher
    {
        private readonly List<string> newsList = new List<string>();
        public delegate void NotifyOvserversHandler(string news);
        public event NotifyOvserversHandler newsPublished;
        public void PublishNews(string news)
        {
            newsList.Add(news);
            newsPublished(newsList[newsList.Count - 1]);
        }
    }

以上,委托聲明了方法的定義,接收一個string類型參數,返回void。事件負責對符合委托定義的、觀察者方法的注冊和取消。

在客戶端使用事件對方法進行注冊。

    class Program
    {
        static void Main(string[] args)
        {
            NewsPublisher publisher = new NewsPublisher();
            NewsSubscriber subscriber = new NewsSubscriber();
            publisher.newsPublished += subscriber.Update;
            publisher.PublishNews("現在是看報時間~");
            Console.ReadKey();
        }
    }

與通過接口實現不同,使用事件注冊的是觀察者的方法,而不是觀察者本身。

總結:無論通過接口實現,還是使用委托和事件,觀察者模式的要素是不變的:被觀察對象,觀察者,被觀察者提供注冊、取消觀察者或觀察者方法,通過被觀察對象的某個方法觸發、通知觀察者。

原文鏈接:https://www.cnblogs.com/darrenji/p/3966626.html

欄目分類
最近更新