paint-brush
.NET C# এ পর্যবেক্ষক ডিজাইন প্যাটার্নের জন্য একটি প্রয়োজনীয় গাইডদ্বারা@ahmedtarekhasan
3,303 পড়া
3,303 পড়া

.NET C# এ পর্যবেক্ষক ডিজাইন প্যাটার্নের জন্য একটি প্রয়োজনীয় গাইড

দ্বারা Ahmed Tarek Hasan19m2023/04/10
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

এই নিবন্ধে, আপনি কিছু বর্ধিতকরণ সহ NET C# ইন অবজারভার ডিজাইন প্যাটার্ন সম্পর্কে শিখবেন। পর্যবেক্ষক ডিজাইন প্যাটার্ন একজন গ্রাহককে একটি প্রদানকারীর সাথে নিবন্ধন করতে এবং বিজ্ঞপ্তি পেতে সক্ষম করে। এটি যেকোন পরিস্থিতির জন্য উপযুক্ত যেখানে পুশ-ভিত্তিক বিজ্ঞপ্তির প্রয়োজন। প্যাটার্নটিকে যা অনন্য করে তোলে তা হল এটি ব্যবহার করে আপনি শক্তভাবে সংযুক্ত সম্পর্ক ছাড়াই এটি অর্জন করতে পারেন।
featured image - .NET C# এ পর্যবেক্ষক ডিজাইন প্যাটার্নের জন্য একটি প্রয়োজনীয় গাইড
Ahmed Tarek Hasan HackerNoon profile picture
0-item

এই নিবন্ধে, আপনি কিছু বর্ধন সহ .NET C#-এ অবজারভার ডিজাইন প্যাটার্ন সম্পর্কে শিখবেন।


পর্যবেক্ষক নকশা প্যাটার্ন সংজ্ঞা

অবজারভার ডিজাইন প্যাটার্ন হল সবচেয়ে গুরুত্বপূর্ণ এবং সাধারণভাবে ব্যবহৃত ডিজাইন প্যাটার্নগুলির মধ্যে একটি।


প্রথমে, অবজারভার ডিজাইন প্যাটার্নের আনুষ্ঠানিক সংজ্ঞা পরীক্ষা করা যাক।


যেমনটি মাইক্রোসফট এর ডকুমেন্টেশন :


পর্যবেক্ষক ডিজাইন প্যাটার্ন একজন গ্রাহককে একটি প্রদানকারীর সাথে নিবন্ধন করতে এবং বিজ্ঞপ্তি পেতে সক্ষম করে। এটি যে কোনও পরিস্থিতির জন্য উপযুক্ত যার জন্য পুশ-ভিত্তিক বিজ্ঞপ্তি প্রয়োজন৷ প্যাটার্নটি একটি প্রদানকারীকে (একটি বিষয় বা একটি পর্যবেক্ষণযোগ্য হিসাবেও পরিচিত) এবং শূন্য, এক বা একাধিক পর্যবেক্ষককে সংজ্ঞায়িত করে। পর্যবেক্ষকরা প্রদানকারীর সাথে নিবন্ধন করে, এবং যখনই একটি পূর্বনির্ধারিত অবস্থা, ঘটনা, বা অবস্থার পরিবর্তন ঘটে, প্রদানকারী স্বয়ংক্রিয়ভাবে সমস্ত পর্যবেক্ষককে তাদের একটি পদ্ধতিতে কল করে অবহিত করে। এই পদ্ধতি কলে, প্রদানকারী পর্যবেক্ষকদের বর্তমান অবস্থার তথ্য প্রদান করতে পারে। .NET-এ, সাধারণ System.IObservable<T> এবং System.IObserver<T> ইন্টারফেস প্রয়োগ করে পর্যবেক্ষক নকশা প্যাটার্ন প্রয়োগ করা হয়। জেনেরিক টাইপ প্যারামিটার সেই ধরনের প্রতিনিধিত্ব করে যা বিজ্ঞপ্তি তথ্য প্রদান করে।


সুতরাং, উপরের সংজ্ঞা থেকে, আমরা নিম্নলিখিতগুলি বুঝতে পারি:

  1. আমাদের দুটি দল বা মডিউল আছে।
  2. যে মডিউলটিতে কিছু তথ্য সরবরাহ করতে হবে। এই মডিউলটিকে বলা হয় প্রোভাইডার (যেমন এটি তথ্য সরবরাহ করে), বা বিষয় (যেমন এটি বাইরের বিশ্বের তথ্যের বিষয়), বা পর্যবেক্ষণযোগ্য (যেমন এটি বাইরের বিশ্ব দ্বারা পর্যবেক্ষণ করা যেতে পারে)।
  3. যে মডিউলটি অন্য কোথাও থেকে আসা তথ্যের প্রবাহে আগ্রহী। এই মডিউলটিকে পর্যবেক্ষক বলা হয় (যেমন এটি তথ্য পর্যবেক্ষণ করে)।

আনস্প্ল্যাশে ডেন হারসন এর ছবি

অবজারভার ডিজাইন প্যাটার্নের সুবিধা

আমরা এখন জানি, অবজারভার ডিজাইন প্যাটার্ন পর্যবেক্ষণযোগ্য এবং পর্যবেক্ষক মডিউলের মধ্যে সম্পর্ক তৈরি করে। যা পর্যবেক্ষক ডিজাইন প্যাটার্নটিকে অনন্য করে তোলে তা হল এটি ব্যবহার করে আপনি শক্তভাবে সংযুক্ত সম্পর্ক ছাড়াই এটি অর্জন করতে পারেন।


প্যাটার্নটি কীভাবে কাজ করে তা বিশ্লেষণ করে আপনি নিম্নলিখিতগুলি পাবেন:

  1. অবজারভেবল অবজারভার সম্পর্কে প্রয়োজনীয় ন্যূনতম তথ্য জানে।
  2. পর্যবেক্ষক অবজারভেবল সম্পর্কে প্রয়োজনীয় ন্যূনতম তথ্য জানেন।
  3. এমনকি পারস্পরিক জ্ঞান বিমূর্তকরণের মাধ্যমে অর্জন করা হয়, কংক্রিট বাস্তবায়ন নয়।
  4. শেষে, উভয় মডিউল তাদের কাজ করতে পারে, এবং শুধুমাত্র তাদের কাজ।

আনস্প্ল্যাশে লুকাস সান্তোসের ছবি

অ্যাবস্ট্রাকশন ব্যবহার করা হয়েছে

এগুলি হল .NET C#অবজারভার ডিজাইন প্যাটার্ন বাস্তবায়নের জন্য ব্যবহৃত বিমূর্ততা



IO পর্যবেক্ষণযোগ্য<T>

এটি একটি Covariant ইন্টারফেস যে কোনো পর্যবেক্ষণযোগ্য প্রতিনিধিত্ব করে। আপনি যদি .NET-এ ভেরিয়েন্স সম্পর্কে আরও জানতে চান, আপনি নিবন্ধটি দেখতে পারেন .NET C#-এ সহভক্তি এবং বৈপরীত্য .


এই ইন্টারফেসে সংজ্ঞায়িত সদস্য হল:


 public IDisposable Subscribe (IObserver<out T> observer);


Subscribe পদ্ধতিটি পর্যবেক্ষণযোগ্যকে জানাতে বলা উচিত যে কিছু পর্যবেক্ষক তার তথ্যের প্রবাহে আগ্রহী।


Subscribe পদ্ধতি একটি বস্তু প্রদান করে যা IDisposable ইন্টারফেস প্রয়োগ করে। এই বস্তুটি পর্যবেক্ষক দ্বারা প্রদত্ত তথ্যের প্রবাহ থেকে সদস্যতা ত্যাগ করতে ব্যবহার করা যেতে পারে। একবার এটি হয়ে গেলে, পর্যবেক্ষককে তথ্যের প্রবাহের কোনো আপডেট সম্পর্কে অবহিত করা হবে না।



IObserver<T> মধ্যে

এটি একটি বিরোধী ইন্টারফেস যা কোনো পর্যবেক্ষকের প্রতিনিধিত্ব করে। আপনি যদি .NET-এ ভেরিয়েন্স সম্পর্কে আরও জানতে চান, আপনি নিবন্ধটি দেখতে পারেন .NET C#-এ সহভক্তি এবং বৈপরীত্য .


এই ইন্টারফেসে সংজ্ঞায়িত সদস্য হল:


 public void OnCompleted (); public void OnError (Exception error); public void OnNext (T value);


OnCompleted পদ্ধতিটি পর্যবেক্ষণযোগ্য দ্বারা কল করা উচিত যাতে পর্যবেক্ষককে জানানো হয় যে তথ্যের প্রবাহ সম্পূর্ণ হয়েছে এবং পর্যবেক্ষকের আর কোনও তথ্য আশা করা উচিত নয়।


OnError পদ্ধতিটি পর্যবেক্ষণযোগ্য দ্বারা কল করা উচিত যাতে পর্যবেক্ষককে জানানো হয় যে একটি ত্রুটি ঘটেছে।


OnNext পদ্ধতিটি পর্যবেক্ষণযোগ্য দ্বারা পর্যবেক্ষককে জানাতে হবে যে তথ্যের একটি নতুন অংশ প্রস্তুত এবং স্ট্রীমে যুক্ত করা হচ্ছে।


আনস্প্ল্যাশে তাদাস সার ছবি

মাইক্রোসফট এর বাস্তবায়ন

এখন, দেখা যাক কিভাবে মাইক্রোসফট C# এ অবজারভার ডিজাইন প্যাটার্ন বাস্তবায়নের সুপারিশ করে। পরে, আমি আপনাকে কিছু ছোটখাটো উন্নতি দেখাব যা আমি নিজে প্রয়োগ করেছি।


আমরা একটি সাধারণ আবহাওয়ার পূর্বাভাস কনসোল অ্যাপ্লিকেশন তৈরি করব। এই অ্যাপ্লিকেশনটিতে, আমাদের কাছে WeatherForecast মডিউল (অবজারভেবল, প্রোভাইডার, বিষয়) এবং WeatherForecastObserver মডিউল (পর্যবেক্ষক) থাকবে।


সুতরাং, এর বাস্তবায়ন অনুসন্ধান শুরু করা যাক.



আবহাওয়ার তথ্য

 namespace Observable { public class WeatherInfo { internal WeatherInfo(double temperature) { Temperature = temperature; } public double Temperature { get; } } }


এটি এমন একটি সত্তা যা তথ্যের স্রোতে প্রবাহিত হওয়া তথ্যের অংশকে প্রতিনিধিত্ব করে।



আবহাওয়ার পূর্বাভাস

 using System; using System.Collections.Generic; namespace Observable { public class WeatherForecast : IObservable<WeatherInfo> { private readonly List<IObserver<WeatherInfo>> m_Observers; private readonly List<WeatherInfo> m_WeatherInfoList; public WeatherForecast() { m_Observers = new List<IObserver<WeatherInfo>>(); m_WeatherInfoList = new List<WeatherInfo>(); } public IDisposable Subscribe(IObserver<WeatherInfo> observer) { if (!m_Observers.Contains(observer)) { m_Observers.Add(observer); foreach (var item in m_WeatherInfoList) { observer.OnNext(item); } } return new WeatherForecastUnsubscriber(m_Observers, observer); } public void RegisterWeatherInfo(WeatherInfo weatherInfo) { m_WeatherInfoList.Add(weatherInfo); foreach (var observer in m_Observers) { observer.OnNext(weatherInfo); } } public void ClearWeatherInfo() { m_WeatherInfoList.Clear(); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. WeatherForecast ক্লাসটি IObservable<WeatherInfo> বাস্তবায়ন করছে।
  2. Subscribe পদ্ধতি প্রয়োগ করার সময়, আমরা পরীক্ষা করি যে পর্যবেক্ষক-এ পাস করা ব্যক্তি আগে থেকেই নিবন্ধিত ছিল কি না। যদি না হয়, আমরা স্থানীয় m_Observers পর্যবেক্ষকদের তালিকায় এটি যোগ করি। তারপরে, আমরা স্থানীয় m_WeatherInfoList তালিকায় থাকা সমস্ত WeatherInfo এন্ট্রিগুলি একে একে লুপ করি এবং পর্যবেক্ষকের OnNext পদ্ধতিতে কল করে পর্যবেক্ষককে এটি সম্পর্কে অবহিত করি।
  3. অবশেষে, আমরা WeatherForecastUnsubscriber ক্লাসের একটি নতুন দৃষ্টান্ত ফেরত দিই যা পর্যবেক্ষক দ্বারা তথ্য প্রবাহ থেকে সদস্যতা ত্যাগ করার জন্য ব্যবহার করা হবে।
  4. RegisterWeatherInfo পদ্ধতিটি সংজ্ঞায়িত করা হয়েছে যাতে প্রধান মডিউলটি নতুন WeatherInfo নিবন্ধন করতে পারে। বাস্তব জগতে, এটি একটি অভ্যন্তরীণ নির্ধারিত API কল বা সিগন্যালআর হাবের শ্রোতা বা অন্য কিছু যা তথ্যের উত্স হিসাবে কাজ করবে দ্বারা প্রতিস্থাপিত হতে পারে।



আনসাবস্ক্রাইবার<T>

 using System; using System.Collections.Generic; namespace Observable { public class Unsubscriber<T> : IDisposable { private readonly List<IObserver<T>> m_Observers; private readonly IObserver<T> m_Observer; private bool m_IsDisposed; public Unsubscriber(List<IObserver<T>> observers, IObserver<T> observer) { m_Observers = observers; m_Observer = observer; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (m_IsDisposed) return; if (disposing && m_Observers.Contains(m_Observer)) { m_Observers.Remove(m_Observer); } m_IsDisposed = true; } ~Unsubscriber() { Dispose(false); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. এটি যেকোনো আন-সাবস্ক্রাইবারের জন্য একটি বেস ক্লাস।
  2. এটি ডিসপোজেবল ডিজাইন প্যাটার্ন প্রয়োগ করে IDisposable প্রয়োগ করে।
  3. কনস্ট্রাক্টরের মাধ্যমে, এটি পর্যবেক্ষকদের সম্পূর্ণ তালিকা নেয় এবং এটি যে পর্যবেক্ষকের জন্য তৈরি করা হয়েছে।
  4. নিষ্পত্তি করার সময়, এটি পর্যবেক্ষকদের সম্পূর্ণ তালিকায় পর্যবেক্ষক ইতিমধ্যেই বিদ্যমান কিনা তা পরীক্ষা করে। যদি হ্যাঁ, এটি তালিকা থেকে এটি সরিয়ে দেয়।



WeatherForecastআনসাবস্ক্রাইবার

 using System; using System.Collections.Generic; namespace Observable { public class WeatherForecastUnsubscriber : Unsubscriber<WeatherInfo> { public WeatherForecastUnsubscriber( List<IObserver<WeatherInfo>> observers, IObserver<WeatherInfo> observer) : base(observers, observer) { } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. এটি Unsubscriber<T> ক্লাস থেকে উত্তরাধিকারসূত্রে পাওয়া যাচ্ছে।
  2. বিশেষ কোনো হ্যান্ডলিং হচ্ছে না।



ওয়েদারফোরকাস্ট অবজারভার

 using System; namespace Observable { public class WeatherForecastObserver : IObserver<WeatherInfo> { private IDisposable m_Unsubscriber; public virtual void Subscribe(WeatherForecast provider) { m_Unsubscriber = provider.Subscribe(this); } public virtual void Unsubscribe() { m_Unsubscriber.Dispose(); } public void OnCompleted() { Console.WriteLine("Completed"); } public void OnError(Exception error) { Console.WriteLine("Error"); } public void OnNext(WeatherInfo value) { Console.WriteLine($"Temperature: {value.Temperature}"); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. WeatherForecastObserver ক্লাসটি IObserver<WeatherInfo> বাস্তবায়ন করছে।
  2. OnNext পদ্ধতিতে, আমরা কনসোলে তাপমাত্রা লিখছি।
  3. OnCompleted পদ্ধতিতে, আমরা কনসোলে "সম্পূর্ণ" লিখছি।
  4. OnError পদ্ধতিতে, আমরা কনসোলে "Error" লিখছি।
  5. মূল মডিউলটিকে নিবন্ধন প্রক্রিয়াটি ট্রিগার করার অনুমতি দেওয়ার জন্য আমরা void Subscribe(WeatherForecast provider) পদ্ধতি সংজ্ঞায়িত করেছি। আন-সাবস্ক্রাইবার অবজেক্ট ফেরত আনসাবস্ক্রাইব করার ক্ষেত্রে ব্যবহার করার জন্য অভ্যন্তরীণভাবে সংরক্ষণ করা হয়।
  6. একই ধারণা ব্যবহার করে, void Unsubscribe() পদ্ধতিটি সংজ্ঞায়িত করা হয়েছে এবং এটি অভ্যন্তরীণভাবে সংরক্ষিত আন-সাবস্ক্রাইবার অবজেক্ট ব্যবহার করে।



কার্যক্রম

 using System; namespace Observable { class Program { static void Main(string[] args) { var provider = new WeatherForecast(); provider.RegisterWeatherInfo(new WeatherInfo(1)); provider.RegisterWeatherInfo(new WeatherInfo(2)); provider.RegisterWeatherInfo(new WeatherInfo(3)); var observer = new WeatherForecastObserver(); observer.Subscribe(provider); provider.RegisterWeatherInfo(new WeatherInfo(4)); provider.RegisterWeatherInfo(new WeatherInfo(5)); observer.Unsubscribe(); provider.RegisterWeatherInfo(new WeatherInfo(6)); observer.Subscribe(provider); provider.RegisterWeatherInfo(new WeatherInfo(7)); Console.ReadLine(); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. আমরা প্রদানকারীর একটি উদাহরণ তৈরি করেছি।
  2. তারপর নিবন্ধিত তথ্য 3 টুকরা.
  3. এই মুহূর্ত পর্যন্ত, কোন পর্যবেক্ষক সংজ্ঞায়িত না থাকায় কনসোলে কিছুই লগ করা উচিত নয়।
  4. তারপর পর্যবেক্ষক একটি উদাহরণ তৈরি.
  5. তারপর প্রবাহে পর্যবেক্ষক সদস্যতা.
  6. এই মুহুর্তে, আমাদের কনসোলে 3টি লগ করা তাপমাত্রা খুঁজে পাওয়া উচিত। এর কারণ হল যখন পর্যবেক্ষক সাবস্ক্রাইব করে, তখন এটি ইতিমধ্যে বিদ্যমান তথ্য সম্পর্কে অবহিত হয় এবং আমাদের ক্ষেত্রে, সেগুলি 3 টি তথ্য।
  7. তারপর আমরা 2 টুকরা তথ্য নিবন্ধন.
  8. সুতরাং, আমরা কনসোলে লগ ইন করা আরও 2টি বার্তা পেয়েছি।
  9. তারপর আমরা আনসাবস্ক্রাইব করি।
  10. তারপরে আমরা 1 টি তথ্য নিবন্ধন করি।
  11. যাইহোক, তথ্যের এই অংশটি কনসোলে লগ করা হবে না কারণ পর্যবেক্ষক ইতিমধ্যেই সদস্যতা ত্যাগ করেছে।
  12. তারপর পর্যবেক্ষক আবার সদস্যতা.
  13. তারপরে আমরা 1 টি তথ্য নিবন্ধন করি।
  14. সুতরাং, তথ্যের এই অংশটি কনসোলে লগ করা হয়েছে।


অবশেষে, এটি চালানো এই ফলাফলের সাথে শেষ হওয়া উচিত:


ছবি আহমদ তারেক


আনস্প্ল্যাশে ব্রুনো ইয়ামাজাকির ছবি

আমার বর্ধিত বাস্তবায়ন

যখন আমি মাইক্রোসফ্টের বাস্তবায়ন পরীক্ষা করেছি, তখন আমি কিছু উদ্বেগ খুঁজে পেয়েছি। তাই, আমি কিছু ছোটখাট পরিবর্তন করার সিদ্ধান্ত নিয়েছি।


IExtendedObservable<out T>

 using System; using System.Collections.Generic; namespace ExtendedObservable { public interface IExtendedObservable<out T> : IObservable<T> { IReadOnlyCollection<T> Snapshot { get; } IDisposable Subscribe(IObserver<T> observer, bool withHistory); } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. IExtendedObservable<out T> ইন্টারফেস IObservable<T> ইন্টারফেসকে প্রসারিত করে।
  2. এটি কোভেরিয়েন্ট । আপনি যদি এই সম্পর্কে আরও জানতে চান, আপনি নিবন্ধটি পরীক্ষা করতে পারেন .NET C#-এ সহভক্তি এবং বৈপরীত্য .
  3. সাবস্ক্রাইব না করেই ইতিমধ্যে বিদ্যমান তথ্য এন্ট্রিগুলির একটি তাত্ক্ষণিক তালিকা পেতে অন্যান্য মডিউলগুলিকে অনুমতি দেওয়ার জন্য আমরা IReadOnlyCollection<T> Snapshot বৈশিষ্ট্যকে সংজ্ঞায়িত করেছি।
  4. আমরা IDisposable Subscribe(IObserver<T> observer, bool withHistory) পদ্ধতিকে হিস্টোরি প্যারামিটারের সাথে একটি অতিরিক্ত bool withHistory সাথে সংজ্ঞায়িত করেছি যাতে পর্যবেক্ষক সিদ্ধান্ত নিতে পারে যে এটি ইতিমধ্যে বিদ্যমান তথ্য এন্ট্রিগুলি সম্পর্কে অবহিত করতে চায় কি না সাবস্ক্রাইব করার মুহূর্তে।



আনসাবস্ক্রাইবার

 using System; namespace ExtendedObservable { public class Unsubscriber : IDisposable { private readonly Action m_UnsubscribeAction; private bool m_IsDisposed; public Unsubscriber(Action unsubscribeAction) { m_UnsubscribeAction = unsubscribeAction; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (m_IsDisposed) return; if (disposing) { m_UnsubscribeAction(); } m_IsDisposed = true; } ~Unsubscriber() { Dispose(false); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. এখন, Unsubscriber ক্লাস জেনেরিক নয়।
  2. এটি কারণ তথ্য সত্তার ধরন জানতে এটির আর প্রয়োজন নেই৷
  3. পর্যবেক্ষক এবং যে পর্যবেক্ষকের জন্য এটি তৈরি করা হয়েছে তাদের সম্পূর্ণ তালিকা অ্যাক্সেস করার পরিবর্তে, এটি নিষ্পত্তি করা হলে এটি পর্যবেক্ষণযোগ্যকে অবহিত করে এবং পর্যবেক্ষণযোগ্য নিজেই নিবন্ধনমুক্তকরণ প্রক্রিয়া পরিচালনা করে।
  4. এইভাবে, এটি আগের চেয়ে কম করছে এবং এটি কেবল তার কাজ করছে।



WeatherForecastআনসাবস্ক্রাইবার

 using System; using System.Collections.Generic; namespace ExtendedObservable { public class WeatherForecastUnsubscriber : Unsubscriber { public WeatherForecastUnsubscriber( Action unsubscribeAction) : base(unsubscribeAction) { } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. আমরা Unsubscriber<T> থেকে <T> অংশটি সরিয়ে দিয়েছি।
  2. এবং এখন কনস্ট্রাক্টর নিষ্পত্তির ক্ষেত্রে ডাকা একটি Action নেয়।



আবহাওয়ার পূর্বাভাস

 using System; using System.Collections.Generic; namespace ExtendedObservable { public class WeatherForecast : IExtendedObservable<WeatherInfo> { private readonly List<IObserver<WeatherInfo>> m_Observers; private readonly List<WeatherInfo> m_WeatherInfoList; public WeatherForecast() { m_Observers = new List<IObserver<WeatherInfo>>(); m_WeatherInfoList = new List<WeatherInfo>(); } public IReadOnlyCollection<WeatherInfo> Snapshot => m_WeatherInfoList; public IDisposable Subscribe(IObserver<WeatherInfo> observer) { return Subscribe(observer, false); } public IDisposable Subscribe(IObserver<WeatherInfo> observer, bool withHistory) { if (!m_Observers.Contains(observer)) { m_Observers.Add(observer); if (withHistory) { foreach (var item in m_WeatherInfoList) { observer.OnNext(item); } } } return new WeatherForecastUnsubscriber( () => { if (m_Observers.Contains(observer)) { m_Observers.Remove(observer); } }); } public void RegisterWeatherInfo(WeatherInfo weatherInfo) { m_WeatherInfoList.Add(weatherInfo); foreach (var observer in m_Observers) { observer.OnNext(weatherInfo); } } public void ClearWeatherInfo() { m_WeatherInfoList.Clear(); } } }


আমরা এখানে যা লক্ষ্য করতে পারি:

  1. এটি IReadOnlyCollection<WeatherInfo> Snapshot সম্পত্তি ছাড়া প্রায় একই যা অভ্যন্তরীণ m_WeatherInfoList তালিকা প্রদান করে কিন্তু IReadOnlyCollection হিসাবে।
  2. এবং IDisposable Subscribe(IObserver<WeatherInfo> observer, bool withHistory) পদ্ধতি যা withHistory প্যারামিটার ব্যবহার করে।



ওয়েদারফোরকাস্ট অবজারভার

 using System; namespace ExtendedObservable { public class WeatherForecastObserver : IObserver<WeatherInfo> { private IDisposable m_Unsubscriber; public virtual void Subscribe(WeatherForecast provider) { m_Unsubscriber = provider.Subscribe(this, true); } public virtual void Unsubscribe() { m_Unsubscriber.Dispose(); } public void OnCompleted() { Console.WriteLine("Completed"); } public void OnError(Exception error) { Console.WriteLine("Error"); } public void OnNext(WeatherInfo value) { Console.WriteLine($"Temperature: {value.Temperature}"); } } }


আমরা এখানে যা লক্ষ্য করতে পারি তা হল Subscribe(WeatherForecast provider) ব্যতীত এটি প্রায় একই যা এখন সিদ্ধান্ত নেয় এটি ইতিহাসের সাথে Subscribe উচিত কিনা।



কার্যক্রম

 using System; namespace ExtendedObservable { class Program { static void Main(string[] args) { var provider = new WeatherForecast(); provider.RegisterWeatherInfo(new WeatherInfo(1)); provider.RegisterWeatherInfo(new WeatherInfo(2)); provider.RegisterWeatherInfo(new WeatherInfo(3)); var observer = new WeatherForecastObserver(); observer.Subscribe(provider); provider.RegisterWeatherInfo(new WeatherInfo(4)); provider.RegisterWeatherInfo(new WeatherInfo(5)); observer.Unsubscribe(); provider.RegisterWeatherInfo(new WeatherInfo(6)); observer.Subscribe(provider); provider.RegisterWeatherInfo(new WeatherInfo(7)); Console.ReadLine(); } } }


আগের মতই আছে।




অবশেষে, এটি চালানোর আগের মতো একই ফলাফলের সাথে শেষ হওয়া উচিত:


ছবি আহমদ তারেক


আনস্প্ল্যাশে এমিলি মর্টারের ছবি, আহমেদ তারেক অ্যাডজাস্ট করেছেন

এরপর কি

এখন, আপনি .NET C# এ অবজারভার ডিজাইন প্যাটার্নের মূল বিষয়গুলি জানেন৷ তবে এখানেই গল্পের শেষ নেই।


IObservable<T> এবং IObserver<T> ইন্টারফেসের উপরে নির্মিত লাইব্রেরিগুলি আরও দুর্দান্ত বৈশিষ্ট্য এবং ক্ষমতা প্রদান করে যা আপনার কাছে দরকারী বলে মনে হতে পারে।


এই লাইব্রেরি হল .NET (Rx) এর জন্য প্রতিক্রিয়াশীল এক্সটেনশন লাইব্রেরি এটি অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং সমর্থন করার জন্য এক্সটেনশন পদ্ধতি এবং LINQ স্ট্যান্ডার্ড সিকোয়েন্স অপারেটরগুলির একটি সেট নিয়ে গঠিত।


অতএব, আমি আপনাকে এই লাইব্রেরিগুলি অন্বেষণ করতে এবং সেগুলি চেষ্টা করার জন্য উত্সাহিত করি৷ আমি নিশ্চিত যে আপনি তাদের কিছু পছন্দ করবেন।


এছাড়াও এখানে প্রকাশিত.