فصل 29 از 40 درس 1 از 1

Event و الگوی Publisher/Subscriber

Event و الگوی Publisher/Subscriber

بخشی از آموزش جامع C# و .NET 10

محتوای درس Event و الگوی Publisher/Subscriber

Event سازوکاری برای اطلاع‌رسانی تغییر یا رخداد از Publisher به Subscriberهاست. این مدل وابستگی مستقیم میان فرستنده و دریافت‌کنندگان را کاهش می‌دهد.

۱. event

کلمه event دسترسی مستقیم مصرف‌کننده به Invocation List را محدود و فقط Subscribe/Unsubscribe را مجاز می‌کند.

مثال

class Clock{public event Action? Tick; public void Raise()=>Tick?.Invoke();}

در این مثال، مفهوم «event» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نام‌ها عمداً ساده انتخاب شده‌اند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب می‌شود.

۲. Publisher و Subscriber

Publisher رخداد را Raise می‌کند و Subscriber Handler خود را ثبت می‌کند.

مثال

var c=new Clock(); c.Tick+=()=>Console.WriteLine("tick"); c.Raise();

در این مثال، مفهوم «Publisher و Subscriber» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نام‌ها عمداً ساده انتخاب شده‌اند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب می‌شود.

۳. EventHandler

EventHandler و EventHandler<TEventArgs> الگوی استاندارد Event در .NET هستند.

مثال

class Job{public event EventHandler? Done; public void Run()=>Done?.Invoke(this,EventArgs.Empty);}

در این مثال، مفهوم «EventHandler» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نام‌ها عمداً ساده انتخاب شده‌اند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب می‌شود.

۴. EventArgs

داده مرتبط با رخداد بهتر است در EventArgs اختصاصی و تغییرناپذیر منتقل شود.

مثال

class ProgressArgs:EventArgs{public int Percent{get;init;}}

در این مثال، مفهوم «EventArgs» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نام‌ها عمداً ساده انتخاب شده‌اند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب می‌شود.

۵. Unsubscribe

برای Objectهای طولانی‌عمر، فراموش کردن Unsubscribe می‌تواند باعث حفظ ناخواسته Reference شود.

مثال

EventHandler h=(_,_)=>Console.WriteLine("done");
         var j=new Job(); j.Done+=h; j.Done-=h;

در این مثال، مفهوم «Unsubscribe» در یک قطعه کد مستقل نمایش داده شده است. مقدارها و نام‌ها عمداً ساده انتخاب شده‌اند تا رفتار اصلی قابل مشاهده باشد؛ در پروژه واقعی همین الگو با مدل دامنه، اعتبارسنجی و مدیریت خطای متناسب ترکیب می‌شود.

۶. مثال‌های عملی

public class OrderService
         {
             public event EventHandler<OrderPlacedEventArgs>? OrderPlaced;
         
             public void Place(Order order)
             {
                 OrderPlaced?.Invoke(this, new OrderPlacedEventArgs(order.Id));
             }
         }

این نمونه عملی چند مفهوم فصل را در کنار هم قرار می‌دهد و برای مشاهده رفتار واقعی کد قابل اجرا و تغییر است.

۷. خطاهای رایج

• Expose کردن Delegate عمومی به‌جای event

• Raise کردن Event از بیرون Publisher

• فراموش کردن Unsubscribe در Lifecycleهای طولانی

۸. نکات اجرایی

• نام‌ها، Typeها و Methodها را متناسب با مفهوم دامنه و بدون ابهام انتخاب کنید.

• هشدارهای کامپایلر و Nullable را بدون بررسی خاموش نکنید.

• منطق هر بخش را تا حد امکان کوچک، قابل تست و مستقل از I/O غیرضروری نگه دارید.

۹. تمرین عملی

کلاس DownloadManager بسازید که پس از تکمیل دانلود Event با درصد و نام فایل منتشر کند.

۱۰. جمع‌بندی

در این فصل، مبانی «Event و الگوی Publisher/Subscriber» با تمرکز بر ساختارهای اصلی زبان، الگوهای صحیح استفاده و خطاهای رایج بررسی شد. تسلط بر این مفاهیم زمینه لازم برای اتصال موضوع به فصل‌های بعدی و طراحی کدهای خواناتر، قابل نگهداری و قابل تست را فراهم می‌کند.