برنامه نویسی واکنش پذیر
در ابتدا یک تعریف از مفهوم برنامه نویسی واکنش پذیر ارائه کنیم:
برنامه نویسی واکنشی یک الگوی برنامه نویسی است و وقتی داده های شما در جریان باشند (مرتب تغییر کنند) معنا پیدا می کند و تغییر مقادیر و ارزش یک متغیر وابسته را در حین تغییر سایر پارامترها به صورت دقیق مشخص می کند. به بیان ساده، اگر یک متغیر وابسته به چند متغیر دیگر است و این متغیرها مرتب تغییر می کنند در صورت پیاده سازی صحیح این مفهوم، همیشه آخرین مقدار (مقدار بروز) پارامتر را به طور خودکار رصد خواهید کرد.
کمی پیچیده شد، با یک مثال، مطلب کاملا روشن خواهد شد.
به عنوان مثال ، x = y + z را تعریف می کنیم. وقتی مقدار y یا z را تغییر می دهیم ، مقدار x به طور خودکار تغییر می کند.
الگوی طراحی Observer
این مدل یک الگوی طراحی نرم افزاری است که یک وابستگی یک به چند بین اشیاء ایجاد می کند. هر زمان که وضعیت یکی از اشیاء ("موضوع" یا "Observable") تغییر کند ، به همه اشیاء دیگر ("Observers") که به آن بستگی دارند ، اطلاع داده می شود.
برای درک بهتر از یک مثال استفاده می کنیم. کاربرانی را فرض کنید که عضو یک فروشگاه شدهاند و درخواست دریافت پیشنهادات ویژه را از طریق ایمیل ثبت کردهاند. کاربران در این حالت ناظر (Observer) هستند. هر زمان پیشنهادی در فروشگاه ایجاد شود، آنها از طریق ایمیل، از پیشنهاد جدید مطلع می شوند. سپس هر کاربر می تواند پیشنهاد را بخرد یا تصمیم بگیرد که در آن لحظه عکسالعملی به آن نداشته باشد.
کاربر ناظر (Observer) همچنین در صورت تمایل می تواند برای دریافت پیشنهادات از سایر فروشگاه ها مشترک شود و ممکن است بعداً به طور کامل از دریافت پیشنهادات هر کدام از آنها منصرف شود.
این الگو، بسیار شبیه به الگوی Publish-Subscribe است. Observable بدون اطلاع از اینکه چه تعداد از ناظران (Observers) در آن مشترک شدهاند یا اصلا آنها چه کسانی هستند، یک Notification برای ناظران (Observers) وابسته منتشر میکند، بدون اینکه نگرانی درباره عملکردی که ممکن است ناظران (Observers) انجام دهند، داشته باشد.
مزایای الگوی طراحی Observer
در این الگوی طراحی، موضوع (Subject) در مورد ناظران (Observers) اطلاعات کمی دارد. تنها چیزی که می داند این است که ناظران (Observers) قرارداد یا Interface خاصی را پیاده سازی یا موافقت می کنند.
موضوع ها بدون دخالت ناظران می توانند مجددا مورد استفاده قرار گیرند و همین امر برای ناظران نیز صدق می کند.
هیچ گونه تغییری در موضوع ایجاد نشده است تا یک ناظر جدید را در خود جای دهد. ناظر جدید فقط باید یک رابط را پیاده سازی کند که موضوع از آن آگاه باشد و سپس برای موضوع ثبت نام کند.
ناظر می تواند در بیش از موضوعی که در آن ثبت شده است ثبت نام کند.
تمام این مزایا به شما امکان اتصال جادویی بین ماژول های موجود در کد شما را می دهد ، این امر باعث می شود تا شما یک طراحی منعطف را برای برنامه خود ایجاد کنید. در ادامه این پست ، ما به چگونگی ایجاد الگوی Observer الگوی خود خواهیم پرداخت ، و همچنین از API داخلی Observer / Observable API و همچنین به کتابخانه های شخص ثالث که می توانند چنین کارکردهایی را ارائه دهند ، استفاده خواهیم کرد. .
بازیگران اصلی الگوی طراحی Observer
1- Observable
کلاسی که جریانی از داده ها یا رویدادها را منتشر می کند. یعنی یک کلاس که میتواند برای انجام برخی اقدامات و انتشار نتیجه استفاده شود.
2- Operator
یک عملگر مقدار تولید (رها) شده توسط Observable را اجرا می کند (اصلاح می کند)
3- Observer
کلاسی که رویدادها یا داده ها را دریافت کرده و براساس آن عمل میکنند. یعنی کلاسی که منتظر است و Observable را تماشا میکند و هر وقت که دیتا تغییر کند یا دیتای جدیدی منتشر شود، نسبت به آن واکنش نشان میدهد.
توجه کنید که ترجمه ی برخی مفاهیم به فارسی، مفهوم را به درستی منتقل نخواهد کرد! لذا به تناوب از همان کلمات انگلیسی استفاده خواهیم کرد تا مطلب جا بیفتد.
یک مثال دیگر برای فهم بیشتر
مراحل دیدن یک فیلم در سینما را مرور می کنیم. شما قبل از اینکه به سینما بروید ابتدا فیلم موردنظر خود را انتخاب می کنید. به سینمایی که فیلم را قرار است نشان بدهد می روید. خوراکی های مخصوصی می خرید. روی صندلی خود می نشینید و منتظر پخش فیلم می شوید. هنگامی که فیلم پخش می شود موارد زیادی در کیفیت دیدن فیلم ما تاثیر خواهد داشت، مانند کیفیت صدا، کیفیت فیلم، دمای سالن و ...
حالا دوباره جریان دیدن فیلم را مرور می کنیم. پرده ی اصلی سینما فیلم را پخش و منتشر می کند. صدا از طریق بلندگوهای سالن به گوش شما می رسد و شما یک همزمانی دقیق بین صدا و تصویر دریافت می کنید و از دیدن فیلم لذت می برید.
در اینجا فیلم Observable است و سالن Operator و تماشاگران که یکی از آنها هم ما هستیم، Observers هستند.
کتابخانه های مرتبط و Reactive Extensions
منظور از Reactive Extension کتابخانه ای است که از اصول برنامه نویسی واکنش پذیر پیروی می کند تا برنامه های غیرهمزمان (asynchronous) و مبتنی بر رویداد (event-based) را با استفاده ازObservable ها تولید کند.
کتابخانه ای که در این مقاله مورد بحث قرار خواهد گرفت RxJava است.RxJava یک پیاده سازی (Implementation) از برنامه نویسی واکنشی، مبتنی بر جاوا است و RxAndroi یک سری کلاس های مخصوص پلتفرم اندروید است که روی کتابخانه RxJava نوشته شده است و از آنها استفاده می کند.
RxJava و انواع Observable ها
در ادامه در مورد انواع Observable در RxJava صحبت خواهیم کرد. انواع Observable ها عبارتند از:
· Observable
این نوع برای وقتی است که قرار است بیش از یک مقدار منتشر شود. برای مثال وقتی یک کاربر می خواهد یک فایل از روی اینترنت دانلود کند و فایل را به صورت یک دیتای پیوسته دریافت کند از این نوع استفاده می کنیم.
· Flowable
این نوع هم شبیه قبلی است با این تفاوت که در این حالت حجم دیتا بسیار زیاد است و ممکن است ناظران نتوانند همه ی مقادیر را دریافت کنند و ممکن است که ناظران برخی از اطلاعات راByPass کنند یا که خطایی در این موراد Raise کنند.
· Single
این نوع وقتی مورد استفاده قرار می گیرد که Observable فقط یک مقدار مانند پاسخ تماس تلفنی را از خود منتشر کند. این رایج ترین نوع است که ما در RxJava از آن استفاده خواهیم کرد زیرا بیشتر برنامه های موبایل یک درخواست ارسال می کنند و یک جواب دریافت می کنند.
· Maybe
همانطور که از اسم این نوع مشخص است، در این نوع ممکن است اصلا چیزی منتشر نشود.
· Completable
این نوع در مواردی مورد استفاده قرار می گیرد که Observable باید بدون اینکه مقداری برگرداند، یک کار به خصوص را انجام دهد.
تمرکز ما در این مقاله روی Single Observable ها است که اغلب نیاز ما که مبتنی بر Network Call است را برطرف می کند.
Observer دارای 4 Interface برای شناختن حالتهای مختلف Observable است.
1- onSubscribe:
وقتی یک Observer به عضویت در Observable در می آید و به آن وصل میشود، این متد فراخوانی می شود.
2- onNext:
این متد زمانی فراخوانی می شود که دیتای جدیدی از سمت Observable منتشر می شود.
3- onError:
این خطا هنگام بروز خطا فراخوانی می شود (وقتی انتشار داده ها با موفقیت انجام نمیشود)
4- onComplete:
این متد زمانی فراخوانی می شود که Observable با موفقیت تمام دیتا را منتشر کند.