محمد صادق مهرافزون
محمد صادق مهرافزون
خواندن ۷ دقیقه·۳ ماه پیش

تفاوت بین Stateflow و Sharedflow

‏StateFlow چیست؟

‏StateFlow یک نگهدارنده حالت (state holder) است. همیشه دارای یک مقدار است (اولیه یا به‌روزرسانی‌شده)، و آخرین مقدار خود را به جمع‌کننده‌هایش(Collectors) ارسال می‌کند. از StateFlow زمانی استفاده می‌شود که بخواهید یک بخش از حالت را نشان دهید که در طول زمان تغییر می‌کند.

‏StateFlow مشابه LiveData است زیرا به شما اجازه می‌دهد تغییرات یک مقدار را مشاهده کنید و به طور خودکار کامپوننت‌های رابط کاربری را وقتی که مقدار تغییر می‌کند، به‌روز رسانی کنید.

نکته:جمع‌کننده‌ یا همان Collector در برنامه‌نویسی با Flow به موجودیتی گفته می‌شود که داده‌های ارسال‌شده توسط یک Flow را دریافت می‌کند. جمع‌کننده‌ها (collectors) مسئول دریافت و پردازش مقادیر جاری از جریان داده‌ها هستند. به طور ساده، Collector همان بخشی از برنامه است که به جریان داده‌ها گوش می‌دهد و به محض دریافت داده‌های جدید، آن‌ها را پردازش می‌کند.
برای مثال، وقتی از یک Flow داده‌هایی را منتشر می‌کنید، یک Collector می‌تواند آن داده‌ها را دریافت کند و بر اساس آن‌ها عملیات خاصی انجام دهد، مانند به‌روزرسانی رابط کاربری یا ذخیره داده‌ها.

مثال برا StateFlow:

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

‏‏SharedFlow چیست؟

‏SharedFlow شبیه به یک کانال پخش (broadcast channel) است. می‌تواند چندین مقدار را ارسال کند و جمع‌کننده‌های (collector) متعددی می‌توانند به آن مقادیر گوش دهند. برخلاف ‏StateFlow ،‏SharedFlow ‏مقدار اولیه ندارد، اما می‌توانید تنظیم کنید که چند مقدار قبلی را برای جمع‌کننده‌های جدید بازپخش کند.

مثالSharedFlow :

تصور کنید یک برنامه چت دارید که کاربران می‌توانند پیام ارسال کنند. وقتی یک کاربر پیام می‌فرستد، همه کاربران آنلاین باید آن را دریافت کنند. SharedFlow می‌تواند برای پخش این پیام‌ها به همه کاربران آنلاین استفاده شود. این امکان را فراهم می‌کند که همه گیرندگان همزمان به داده‌های پخش شده دسترسی داشته باشند.


تفاوت های StateFlow و SharedFlow

نوع داده:

  • ‏‏‏نوع داده StateFlow: نمایانگر یک حالت قابل تغییر (mutable) است که در طول زمان تغییر می‌کند. فقط آخرین حالت را به جمع‌کننده‌های خود ارسال می‌کند.
  • نوع داده ‏SharedFlow: نمایانگر یک جریان از مقادیری است که در طول زمان ارسال می‌شوند. می‌تواند مقادیر متعددی را به جمع‌کننده‌ها ارسال کند.

تغییرپذیری:

  • تغییرپذیری StateFlow: حالتی که توسط StateFlow نگهداری می‌شود قابل تغییر است و می‌توان آن را با استفاده از ویژگی value به‌روزرسانی کرد.
  • تغییرپذیری ‏SharedFlow: مقادیری که توسط SharedFlow ارسال می‌شوند، غیرقابل تغییر هستند؛ زمانی که یک مقدار ارسال شد، دیگر قابل تغییر نیست.

رفتار در زمان اشتراک‌گذاری:

  • اشتراک‌گذاری ‏StateFlow: زمانی که جمع‌کننده‌ای به StateFlow مشترک می‌شود، بلافاصله آخرین وضعیت موجود را دریافت می‌کند. این ویژگی برای سناریوهایی مثل اپلیکیشن‌های بانکی که کاربر باید همیشه آخرین وضعیت حساب خود را مشاهده کند، بسیار مفید است.
  • ‏اشتراک‌گذاری SharedFlow: وقتی جمع‌کننده‌ای به SharedFlow مشترک می‌شود، هیچ مقداری بلافاصله دریافت نمی‌کند و فقط مقادیری که پس از شروع جمع‌آوری ارسال شده‌اند را دریافت می‌کند. مثل زمانی که در یک گروه پیام‌رسانی به تازگی عضو می‌شوید و پیام‌های جدید را دریافت می‌کنید.
نکته: در اینجا "مشترک می‌شود" به معنای Subscribe کردن به یک جریان داده است. وقتی می‌گوییم جمع‌کننده‌ای (collector) به StateFlow* یا SharedFlow مشترک می‌شود، یعنی آن جمع‌کننده به این جریان متصل می‌شود تا بتواند داده‌ها یا تغییرات حالت را از جریان دریافت کند.
در واقع، در برنامه‌نویسی زمانی که یک جمع‌کننده به یک جریان مشترک می‌شود، از آن نقطه به بعد هر داده یا تغییر جدیدی که در جریان اتفاق بیفتد، به جمع‌کننده ارسال می‌شود. این فرآیند به طور غیرهمزمان (asynchronous) و بدون نیاز به درخواست مکرر جمع‌کننده انجام می‌شود.
مثلاً در یک اپلیکیشن چت، اگر شما به SharedFlow پیام‌ها مشترک شوید، هر پیام جدیدی که در چت ارسال شود به شما نمایش داده می‌شود.

هم‌ترازی مقادیر (Conflation):

  • هم‌ترازی مقادیر ‏StateFlow: به طور خودکار مقادیر ارسال‌شده را هم‌تراز می‌کند، به این معنا که فقط آخرین وضعیت را جمع‌کننده‌ها دریافت می‌کنند. این ویژگی زمانی مفید است که به‌روزرسانی‌های سریع و مداوم داریم، مثل وضعیت آب‌وهوا که فقط آخرین تغییر مهم است.
  • ‏هم‌ترازی مقادیر SharedFlow: مقادیر ارسال‌شده را هم‌تراز نمی‌کند؛ همه مقادیر ارسال‌شده تا زمانی که جمع‌آوری شوند، در دسترس هستند. این ویژگی برای مواردی مثل نوتیفیکیشن‌های یک فروشگاه آنلاین مفید است، جایی که هر به‌روزرسانی و پیام ممکن است مهم باشد.
نکته: "هم‌تراز" به معنی Conflation در زمینه‌ی برنامه‌نویسی با جریان‌های داده (مثل Flow، StateFlow و SharedFlow) است. وقتی می‌گوییم یک جریان داده "هم‌تراز" می‌شود، منظور این است که اگر مقادیر زیادی به سرعت ارسال شوند، فقط آخرین مقدار به جمع‌کننده‌ها (collectors) ارائه می‌شود و مقادیر قبلی که هنوز پردازش نشده‌اند نادیده گرفته می‌شوند.
به عبارت دیگر، هم‌ترازی به معنای این است که مقادیر قبلی حذف می‌شوند تا فقط آخرین مقدار برای جمع‌کننده ارسال شود. این ویژگی در StateFlow به‌طور پیش‌فرض وجود دارد.
به عنوان مثال:فرض کنید شما یک اپلیکیشن وضعیت آب‌وهوا دارید که به سرعت تغییرات دمایی را دریافت می‌کند. اگر جریان هم‌تراز باشد، فقط آخرین دما به جمع‌کننده ارسال می‌شود و تغییرات قبلی نادیده گرفته می‌شوند. این باعث می‌شود که رابط کاربری شما فقط آخرین وضعیت را نمایش دهد و نیازی به پردازش تمام تغییرات قبلی نداشته باشد.
در مقابل، در SharedFlow چنین هم‌ترازی به‌طور خودکار وجود ندارد و همه مقادیر به ترتیب به جمع‌کننده‌ها ارائه می‌شوند، مگر اینکه خودتان آن را تنظیم کنید.

بافرینگ:

  • بافرینگ ‏StateFlow: توانایی بافر کردن ندارد، زیرا تنها یک حالت واحد را نشان می‌دهد.
  • بافرینگ SharedFlow: می‌تواند مقادیر ارسال‌شده را برای جمع‌کننده‌هایی که به‌صورت فعال مصرف نمی‌کنند، بافر کند، بر اساس اندازه بافر و استراتژی سرریز تعیین‌شده. این ویژگی برای اپلیکیشن‌های شبکه‌ای مثل استریم موسیقی که باید داده‌ها را در زمان مناسب به مصرف‌کننده‌ها ارائه دهند، مفید است.
نکته: بافرینگ (Buffering) در زمینه جریان‌های داده (Flow) به معنای ذخیره‌سازی موقت داده‌ها قبل از ارسال به جمع‌کننده‌ها (collectors) است. وقتی بافر فعال باشد، داده‌های ارسال‌شده در بافر ذخیره می‌شوند تا جمع‌کننده‌ها بتوانند بعداً آن‌ها را دریافت و پردازش کنند.
به بیان ساده‌تر، اگر جریان داده به سرعت مقادیر جدید تولید کند ولی جمع‌کننده نتواند به همان سرعت آن‌ها را پردازش کند، بافر داده‌ها را موقتاً ذخیره می‌کند تا وقتی جمع‌کننده آماده شد، داده‌های ذخیره‌شده را دریافت کند. این امر کمک می‌کند که داده‌ها از دست نروند.
مثال:
فرض کنید در یک اپلیکیشن چت، پیام‌های زیادی از سوی کاربران ارسال می‌شود. اگر کاربر یا سرور شما نتواند همه پیام‌ها را به‌سرعت پردازش کند، بافر کردن پیام‌ها به شما کمک می‌کند تا همه پیام‌ها به‌طور موقت ذخیره شوند و بعداً به کاربر نمایش داده شوند.

ارتباط یک به چند یا چند به چند:

  • ‏ارتباط StateFlow: معمولاً برای ارتباط یک به چند استفاده می‌شود؛ یعنی چندین جمع‌کننده وضعیت مشترکی را مشاهده و به آن واکنش نشان می‌دهند. مثال: حالت لاگین کاربران در یک اپلیکیشن بانکداری که همه اجزای رابط کاربری باید وضعیت ورود یا خروج کاربر را بدانند.
  • ‏ارتباط SharedFlow: برای سناریوهای چند به چند مناسب است، جایی که چند تولیدکننده می‌توانند مقادیر را ارسال کنند و چندین جمع‌کننده نیز به طور مستقل آن‌ها را مصرف می‌کنند. مثال: چت‌های گروهی در یک اپلیکیشن پیام‌رسان.

مقداردهی اولیه:

  • مقداردهی اولیه ‏StateFlow: باید با یک وضعیت اولیه از طریق سازنده MutableStateFlow مقداردهی اولیه شود. مثلاً، در شروع یک اپلیکیشن پخش ویدیو، حالت پیش‌فرض می‌تواند "توقف‌شده" باشد.
  • مقداردهی اولیه ‏SharedFlow: می‌تواند بدون مقدار اولیه ایجاد شود و به محض در دسترس بودن مقادیر شروع به ارسال آن‌ها کند. مثل داده‌های حسگرها در یک اپلیکیشن ردیابی سلامت که با شروع فعالیت کاربر ارسال می‌شوند.

استفاده در رابط کاربری (UI):

  • ‏رابط کاربری StateFlow: اغلب در کدهای مربوط به UI برای نمایش حالت‌های UI استفاده می‌شود که نیاز به مشاهده توسط چندین جزء رابط کاربری دارند. مثل حالت‌های صفحه ورود که وضعیت ورود یا خروج کاربر را نمایش می‌دهد.
  • رابط کاربری ‏SharedFlow: برای مدیریت رویدادهای غیرهمزمان یا جریان‌های داده مفید است، جایی که بخش‌های مختلف برنامه نیاز به اطلاع از تغییرات دارند. مثل نوتیفیکیشن‌های لحظه‌ای در اپلیکیشن‌های خرید آنلاین که همه مشتریان باید از رویدادها مطلع شوند.


نتیجه‌گیری:

‏StateFlow برای مدیریت حالت‌های متغیر و نمایش آخرین وضعیت به چندین جمع‌کننده مناسب است، مانند به‌روزرسانی رابط کاربری. این جریان همواره آخرین مقدار را نگه می‌دارد و به محض اشتراک‌گذاری، آن را به جمع‌کننده‌ها ارسال می‌کند. SharedFlow ‏برای پخش چندین مقدار به جمع‌کننده‌های متعدد در طول زمان کاربرد دارد. این جریان برای مواردی که نیاز به مدیریت رویدادهای متوالی (مثل پیام‌ها یا نوتیفیکیشن‌ها) است، مناسب بوده و قابلیت بافرینگ و بازپخش مقادیر را دارد.

هر دو ابزار قدرتمندی برای مدیریت داده‌ها در سناریوهای مختلف برنامه‌نویسی اندروید هستند.


ممنون که تا آخر این پست همراه من بودید ، امیدوارم براتون مفید بوده باشه 🙌🙏✌ (:

بقیه آموزش های من با نام (mister developer) را می توانید در تلگرام و اینستاگرام دنبال کنید!!

کانال تلگرام: mister_developerr

اینستاگرام: mister_developerr

موفق و پیروز باشید

kotlinبرنامه نویسیکاتلین
شاید از این پست‌ها خوشتان بیاید