نــاظـــر (Observer)
هـــدف
الگوی طراحی رفتاری Observer (ناظر) به شما اجازه میدهد یک مکانیسم اشتراک را تعریف کنید تا چندین شیء را در مورد هر رویدادی که برای شیء مورد مشاهده آنها اتفاق میافتد اطلاع دهد.
مـسئـــلـه
تصور کنید که دو نوع شیء دارید: یک مشتری و یک فروشگاه. مشتری به یک برند خاص از محصول (مثلاً مدل جدید آیفون) بسیار علاقهمند است که باید خیلی زود در فروشگاه موجود شود.
مشتری میتواند هر روز به فروشگاه مراجعه کند و در دسترس بودن محصول را بررسی کند. اما در حالی که محصول هنوز در مسیر است، بیشتر این سفرها بیفایده خواهد بود.
مراجعه به فروشگاه در مقابل ارسال اسپم
از طرف دیگر، فروشگاه میتواند انبوهی از ایمیلها (که ممکن است اسپم تلقی شود) را هر بار که محصول جدیدی در دسترس قرار میگیرد به تمام مشتریان ارسال کند. این کار برخی از مشتریان را از سفرهای بیانتهای به فروشگاه نجات میدهد. در عین حال، مشتریان دیگری را که به محصولات جدید علاقهای ندارند، ناراحت میکند.
به نظر میرسد با یک تضاد مواجه هستیم. یا مشتری وقت خود را برای بررسی در دسترس بودن محصول هدر میدهد یا فروشگاه منابع خود را برای اطلاعرسانی به مشتریان اشتباه هدر میدهد.
راهــکــــار
شیء که دارای حالت جالبی است اغلب موضوع نامیده میشود، اما از آنجایی که همچنین قصد دارد اشیاء دیگر را در مورد تغییرات در حالت خود اطلاع دهد، آن را ناشر خواهیم نامید. تمام اشیاء دیگری که میخواهند تغییرات در حالت ناشر را ردیابی کنند، مشترک نامیده میشوند.
الگوی ناظر پیشنهاد میکند که شما یک مکانیسم اشتراک را به کلاس ناشر اضافه کنید تا اشیاء فردی بتوانند برای جریان رویدادهای دریافتی از آن ناشر مشترک شوند یا از آن لغو اشتراک کنند. نترسید! همه چیز به پیچیدگی آنچه به نظر میرسد نیست. در واقع، این مکانیسم شامل ۱) یک فیلد آرایهای برای ذخیره لیستی از مراجع به اشیاء مشترک و ۲) چندین متد عمومی است که اجازه میدهد مشترکان را به این لیست اضافه یا از آن حذف کنید.
یک مکانیسم اشتراک به اشیاء فردی اجازه میدهد تا برای اطلاعیههای رویداد مشترک شوند.
اکنون، هر زمان که یک رویداد مهم برای ناشر اتفاق میافتد، ناشر از مشترکان خود عبور میکند و متد اطلاعرسانی خاص را در اشیاء آنها فراخوانی میکند.
برنامههای واقعی ممکن است دهها کلاس مشترک مختلف داشته باشند که علاقهمند به ردیابی رویدادهای همان کلاس ناشر هستند. شما نمیخواهید ناشر را به همه این کلاسها متصل کنید. علاوه بر این، ممکن است از قبل برخی از آنها را نشناسید اگر قرار باشد کلاس ناشر توسط افراد دیگر استفاده شود.
به همین دلیل بسیار مهم است که تمام مشترکان یک رابط مشترک را پیادهسازی کنند و ناشر فقط از طریق آن رابط با آنها ارتباط برقرار کند. این رابط باید متد اطلاعرسانی را همراه با مجموعهای از پارامترهایی که ناشر میتواند از آنها برای انتقال برخی دادههای زمینه همراه با اطلاعرسانی استفاده کند، اعلام کند.
ناشر با فراخوانی متد اطلاعرسانی خاص روی اشیاء آنها، مشترکان را اطلاع میدهد.
اگر برنامه شما چندین نوع مختلف ناشر دارد و میخواهید مشترکان خود را با همه آنها سازگار کنید، میتوانید حتی بیشتر پیش بروید و تمام ناشران را وادار کنید که از یک رابط مشترک پیروی کنند. این رابط فقط نیاز دارد چندین متد اشتراک را توصیف کند. این رابط به مشترکان اجازه میدهد تا بدون اتصال به کلاسهای مشخص آنها، حالتهای ناشران را مشاهده کنند.
مقایسه با دنیای واقعی
اشتراک مجله و روزنامه
اگر مشترک یک روزنامه یا مجله هستید، دیگر نیازی نیست به فروشگاه بروید تا بررسی کنید که آیا شماره بعدی در دسترس است یا خیر. در عوض، ناشر نسخههای جدید را بلافاصله پس از انتشار یا حتی قبل از آن مستقیماً به صندوق پستی شما ارسال میکند.
ناشر لیستی از مشترکان را نگهداری میکند و میداند که آنها به کدام مجلات علاقه دارند. مشترکان میتوانند هر زمان که بخواهند ارسال نسخههای جدید مجله به آنها توسط ناشر را متوقف کنند، از این لیست خارج شوند.
ســاخــتـــار
برای مطـالعـه متن کامل مقالــه، مجموعه کــــدها، نحوه پیاده سازی، مزایا و معایب و روابط با الگوهای دیگر، ایــنــجـــا کلیک کنید.