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» با تمرکز بر ساختارهای اصلی زبان، الگوهای صحیح استفاده و خطاهای رایج بررسی شد. تسلط بر این مفاهیم زمینه لازم برای اتصال موضوع به فصلهای بعدی و طراحی کدهای خواناتر، قابل نگهداری و قابل تست را فراهم میکند.