الگویِ طراحیِ Observer (جاوا و کاتلین)

فرض کنید یک دماسنج دارید ، سنسوری به این دماسنج وصل می‌کنید که به محض اینکه دما تغییر پیدا کرد بر حسب درجه یک کاری را انجام دهد (مثلا موتور رو خاموش کنه) ، این مثال دقیقا همون چیزیه که در این الگو انجام میشه !

در این الگو یک شئ تغییر وضعیت می‌کنه و شئ یا اشیای دیگه تغییر وضعیت اون رو Observe یا مشاهده می‌کنند ، شئ‌ای که تغییراتش مورد بررسی و مشاهده قرار می‌گیره Subject یا Observable و اشیایی که مشاهده‌کننده هستند رو Observer یا Listener صدا می‌زنند .

در اندروید کتاب‌خانه‌هایی مثل RxJava/RxAndroid/RxKotlin و BroadcastListener و LiveData بر اساس این الگو کار می‌کنند .

برای پیاده سازی راه‌های مختلفی وجود داره ، یکیش اینه که از پایه خودتون پیاده‌سازی کنید ، یکیش استفاده از Observer که یک interface در جاوا بوده هست و یکیش استفاده از PropertyChangeListener (که بازم یک interface در جاوا هست) ، به خاطر اینکه PropertyChangeListener ارجح بر Observer حساب میشه (Observer در جاوا 9 منسوخ شده) ما هم بر همین اساس مثال رو می‌زنیم ، PropertyChangeListener در واقع همون Observer هست و کلاسِ Observable یا Subject هم یک پارامتر با جنسِ PropertyChangeSupport در خودش داره که به محض تغییر به اصلاح fire انجام میده و به اطلاع PropertyChangeListener می‌رسونه

صورت مساله

دماسنجی داریم ، به محض تغییرات دما اگر دما بالاتر از 80 درجه شد موتور خاموش شود و اگر پایین‌تر از 80 بود موتور روشن شود .

اول کلاسِ Thermometer رو که همون دماسنج هست ایجاد می‌کنیم ، این کلاس یک PropertyChangeSupport در خودش داره و یک متغیر به نام temperature (دما) ، ما سه تابع رو پیاده‌سازی می‌کنیم ، یکی یک custom set برای temperature ، یکی addPropertyChangeListener که یک PropertyChangeListener رو به PropertyChangeSupport وصل می‌کنه و یک removePropertyChangeListener که PropertyChangeListener رو قطع می‌کنه (و دیگه بعد از اون در صورت تغییر چیزی به اطلاعِ Observer یا PropertyChangeListener نمی‌رسه) :

https://gist.github.com/sasssass/5564894a7c7b8f7e956fb4af28a2a147

تابع firePropertyChange در این کد سه ورودی داره ، یکی اسم یا یک Tag برای متغیر ، دومی مقدار قدیمی ، سومی مقدار جدید .

حالا نیاز به یک کلاس به اسم ElectricMotor داریم ، این کلاس قراره Thermometer رو Observe کنه و به محضِ تغییراتِ دمای اون عملی رو انجام بده ، این کلاس implement شده از PropertyChangeListener هست و کلاسِ Observer حساب میشه ، تابع propertyChange به خاطر implement شدن از PropertyChangeListener باید override بشه که این تابع همون تابعی که به محضِ تغییراتِ دما اجرا میشه :

https://gist.github.com/sasssass/0e5f4bdb06f16d3f4fb85ee324386d5f

و الان می‌تونیم از کد‌ها استفاده کنیم :

https://gist.github.com/sasssass/ea9df7fc53e1f7b0745c4dfd4ce04392

و طبقِ لاگ باید اول عملیات observe انجام بشه ولی بعد از سه بار تغییرات به خاطر اینکه observer رو قطع کردیم دیگه نباید Log داشته باشیم :

باقی مقالات در مورد الگوی‌های طراحی رو در این مقاله بخونید .

من رو در لینکدین و اینستاگرام دنبال کنید ???

اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???