Observer Pattern

android observer pattern الگوی طراحی design pattern اندروید مشاهده گر مشاهده کنند آبزرور آبزروبل

سطح آموزش: #پیشرفته

در آینده نزدیک قصد دارم وارد مباحث پیشرفته‌تری بشم و راجع به RxAndroid صحبت کنم. ولی قبل از اون احتیاج داریم با الگوی Observer یا مشاهده‌گر آشنا بشیم.

Observer Pattern (الگوی مشاهده‌گر)

بخش اعظمی از Object Oriented Programming یا برنامه‌نویسی شی گرا (OOP) به اشیاء و اثرمتقابلشون روی هم وابسته‌ست. بسیاری از مواقع پیش میاد که یک شی احتیاج داره از تغییراتی که روی شی دیگه حاصل شده آگاه بشه. و همونطور که تا حالا دیدیم یکی از بزرگترین اهداف ما تو طراحی الگو‌های مختلف جداسازی و کم کردن وابستگی‌هاست (مثل کاری که توی تزریق وابستگی می‌کردیم).

از این الگو میتونیم هروقت که نیاز داریم یک شی توسط یک یا چند مشاهده‌گر دیده بشه استفاده کنیم.

شبه کد زیر رو در نظر بگیرید:

کد

توی خط ۳ مقدار c برابر با مجموع a و b قرار داده شد. ولی در خط بعدی که مقدار a زیاد شد دیگه c مجموع a و b نبود. چرا که a تغییر کرده بود. اما اگر بخوایم همیشه c مجموع a و b باشه باید چی کار کنیم؟ اگر با برگه‌های excel کار کرده باشید میدونید که خیلی از این خاصیت استفاده میشه. برای مثال فرض کنید یک بنگاه مالی هست که  میزان سود در فصول مختلف تغییر می‌کنه. حالا ما میخوایم درآمد خالص رو حساب کنیم در زمان‌های مختلف حساب کنیم. چطور میتونیم متغیر‌های مربوط به درآمد رو به تغییرات سود حساس کنیم؟

 

برای چنین کاری نیاز به مشاهده‌گر(Observer) و مشاهده شونده(Observable)داریم. observer کسیه که تغییرات رو مشاهده میکنه (مثلا عدد c که میخوایم تغییراتِ a و b رو مشاهده کنه یا مقدار درآمد که باید سود رو مشاهده کنه) و observable کسیه که مورد مشاهده قرار میگیره. (تغییرات a و b و سود در مثال‌هایی که زدم)

هر Observer میتونه تنها یک Observable رو مشاهده کنه در حالیکه هر Observable میتونه چندین Observer داشته باشه. یعنی یک رابطه one to many داریم.

شاید براتون سوال پیش بیاد که اینجا c که Observer هست داره همزمان a و b رو مشاهده می‌کنه. اما این دقیق نیست. متغیر نیست مشاهده‌گر نیست. بلکه ما یک مشاهده‌گر (از جنس تابع) خواهیم نوشت که عمل مشاهده رو انجام بده و سپس c رو به تناسب تغییر بده. برای a و b هم دو متد خواهیم نوشت که یکی تغییرات a رو روی c اعمال کنه و دیگری تغییرات b.

هدف در Observer Pattern چیست؟

تعریف یک وابستگی یک به چند (one-to-many dependency) بین اشیاء به طوری که وقتی یک شی (Observable) تغییر میکنه تمامی وابستگی‌هاش (observer) به طور خودکار تغییر کنن.

تصویر زیر که از این آدرس کپی کردم میتونه به درک بهتر این مفهوم کمک کنه.

دیاگرام رابطه بین observer و observable

توضیح

Observable – یک اینترفیس یا کلاس abstract هست که عملیات لازم برای اضافه کردن و حذف کردن observerها به شیء مورد نظر رو پیاده می‌کنن. توی کتاب Design Patterns: Elements of Reusable Object-Oriented Software از واژه Subject هم استفاده شده۱.

ConcreteObservable – واژه concrete در واقع مخالف abstract هست. همونطور که میدونید توی کلاس abstract هیچ logic خاصی نوشته نمیشه. در نقطه مقابل ConcreteObservabe شامل منطق کارِ observable هست. مقدار شیء رو نگهداری می‌کنه و وقتی تغییری در این مقدار ایجاد میشه observerها رو مطلع میکنه.

Observer – یک interface یا کلاس abstract هست که عملیات‌های لازم برای انجام بعد از آگاه شدن از تغییر رو داره.

ConcreteObserverA و ConcreteObserverB – پیاده‌سازی observerها هستن. دو تا هستن تا بهمون بگه میشه بیش از یک مشاهده‌گر برای یک مشاهده‌شونده داشت۲.

عملکرد

توی فریمورک اصلی ابتدا ConcreteObservabe رو می‌نویسیم سپس ConcreteObserverها رو می‌نویسیم و به observable متصل (attach) می‌کنیم. هر بار که شیء تغییری داشته باشه تمامی observerهای متصل توسط متدهایی که در اینترفیس observer هست مطلع میشن و کدهایِ داخلشون اجرا میشه. با اضافه شدن observer جدید هم تنها کافیه ما اون به attach کنیم و برنامه به درستی کار می‌کنه.

یک مثال برای اهمیت Observer Pattern

 

 

سبد خرید سایت دیجی‌کالا رو در نظر بگیرید. با اضافه شدن هر آیتم سبد خرید محصول تغییر می‌کنه. شاید بشه با یک یا چند حلقه هر بار مجموع قیمت‌ها و تخفیف‌ها و غیره رو حساب کرد تا به سبد خرید رسید. ولی ساده‌تر نیست با اضافه شدن هر محصول به طور خودکار سبد خرید آپدیت بشه. یعنی بهتر نیست سبد خرید نسبت به تغییرات آگاه باشه؟

حالا فرض کنید به همین سبد خرید قرار هست که امکان کد تخفیف هم اضافه بشه. اگر از الگوی درست استفاده نشده باشه باید به سراغ تک‌تک حلقه‌هایی که نوشتید برید و کد تخفیف رو هم لحاظ کنید. اما اگر از Observer Pattern استفاده کرده باشید تنها کافیه مقدار تخفیف رو هم به منطق سیستم اضافه کنید.

 

Observer Pattern در مدل۳ MVP (یا MVC یا MVVM)

همونطور که میدونید هدف اصلی در این مدل‌ها جداسازی بخش‌های مختلف از هم هست. Observer Pattern یکی از پترن‌های پر استفاده در این مدل‌هاست چرا که میشه view رو observer و model رو observable تعریف کرد و به این شیوه بدون اینکه ناچار باشیم از این دو کنار یکدیگر استفاده کنیم اون‌ها رو به هم مرتبط کنیم.

Observer Pattern در رخدادها

احتمالا تا الان خودتون هم متوجه شدید که مکانیزم رفتاری Listenerها در اندروید کاملا منطبق بر الگوی observer هست. به بیان دیگه وقتی شما از Listenerها استفاده می‌کنید دارید از پترن observer که observable استفاده می‌کنید که interfaceهاش توسط توسعه دهنده‌های گوگل نوشته شده.

 

 


۱- من این بخش رو مستقیما از سایتی که بالاتر گفتم ترجمه کردم. از اونجایی که این کتاب مرجع محسوب میشه دونستن این مطلب حتما برای مطالعه متون آموزشی مفیده.

۲- من به عمد از لغات فارسی و انگلیسی استفاده می‌کنم که با هر دو اصطلاح آشنا بشید و حداقل برای من ترجمه کمک میکنه بهتر عملکرد رو درک کنم.

۳- همونطور که توی پست‌های مربوطه توضیح دادم نمیشه مرز مشخصی بین این روش‌ها در نظر گرفت. بخصوص از اونجایی که تعریف مشخصی برای این پترن‌ها نیست ممکنه پیاده سازی یک نفر از mvvm همون mvc باشه. دلیل استفاده از نام‌های مختلف هم گفتن تفاوت در روش‌های نگاه به مسئله دیزاین پترن بوده.

 

12 دیدگاه برای “Observer Pattern

    1. این پست و Iterator Pattern مقدمه‌ای هستن برای آموزش استفاده از RxAndroid و RxJava که تا چند وقت دیگه روی سایت منتشر می‌کنم.
      بعد هم مجموع پست‌های دیزاین پترن رو کنار هم قرار میدیم تا به یک پترن کلی برای توسعه اندروید با استفاده از تمام پترن‌ها برسیم.

  1. سلام روز بخیر من سوالی داشتم راجب اررتباط دوطرفه بین ui thread و background service در اندروید
    چطور امکانش هست با استفاده Observer و bus event این ارتباط برقرار کرد (مثه لیست چت برنامه های چت البته بدون در نظر گرفتن دیتا بیس) ؟؟و ایا کلا این روش درست هست ؟؟؟

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *