ویرگول
ورودثبت نام
محمد رئیسی
محمد رئیسیبرنامه نویس اندروید
محمد رئیسی
محمد رئیسی
خواندن ۳ دقیقه·۱ ماه پیش

درک تفاوت Cold Flow و Hot Flow با مثال معلم خصوصی و کلاس درس

در کار با Kotlin Flow، یکی از رایج‌ترین ابهام‌ها، تفاوت بین Cold Flow و Hot Flow است؛ مخصوصاً زمانی که چند بخش مختلف از برنامه می‌خواهند به تغییرات یک مقدار واکنش نشان بدهند.

برای درک ساده و ماندگار این تفاوت، می‌توانیم از یک مثال آموزشی استفاده کنیم:
👉 معلم خصوصی در مقابل کلاس درس


Cold Flow؛ مثل معلم خصوصی

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

در دنیای Kotlin Flow، این دقیقاً رفتار Cold Flow است.

ویژگی‌های Cold Flow

  • هر collect باعث شروع یک اجرای جدید می‌شود

  • منطق بالادستی Flow به ازای هر collector دوباره اجرا می‌شود

  • هیچ داده‌ای بین collectorها به اشتراک گذاشته نمی‌شود

  • side-effectها (مثل لاگ، خواندن دیتابیس، شبکه) تکرار می‌شوند


نمونه کد: Cold Flow

val coldFlow = flow { println("Flow started") emit(loadFromDatabase()) }

جمع‌آوری در دو جای مختلف:

launch { coldFlow.collect { println("Collector A: $it") } } launch { coldFlow.collect { println("Collector B: $it") } }

خروجی:

Flow started Flow started Collector A: data Collector B: data

📌 کد داخل Flow دو بار اجرا شده؛ درست مثل معلم خصوصی که برای دو شاگرد جداگانه، درس را از اول می‌گوید.


Hot Flow؛ مثل کلاس درس

حالا یک کلاس درس را تصور کنید.
معلم یک بار تدریس می‌کند و همه‌ی دانش‌آموزان هم‌زمان گوش می‌دهند. ورود یا خروج دانش‌آموزها تأثیری روی خود تدریس ندارد.

این دقیقاً رفتار یک Hot Flow است.

ویژگی‌های Hot Flow

  • تولید داده مستقل از collectorها انجام می‌شود

  • مقدارها بین همه‌ی collectorها مشترک هستند

  • side-effect فقط یک بار اتفاق می‌افتد

  • چند collector می‌توانند با خیال راحت هم‌زمان گوش بدهند


نمونه کد: SharedFlow (Hot Flow)

val sharedFlow = MutableSharedFlow<Int>()

چند collector:

launch { sharedFlow.collect { println("Collector A: $it") } } launch { sharedFlow.collect { println("Collector B: $it") } }

ارسال مقدار:

sharedFlow.emit(1)

خروجی:

Collector A: 1 Collector B: 1

📌 مقدار یک بار تولید شده و به همه رسیده؛ درست مثل تدریس در کلاس.


Replay؛ اگر کسی دیر وارد کلاس شود چه می‌شود؟

ویژگی replay مشخص می‌کند که چند مقدار آخر برای collectorهای جدید نگه داشته شود.


SharedFlow بدون replay (replay = 0)

مثل کلاس زنده بدون ضبط:

  • اگر دانش‌آموز دیر برسد، مطالب قبلی را از دست می‌دهد

MutableSharedFlow<Int>(replay = 0)

SharedFlow با replay = 1

مثل کلاسی که آخرین اسلاید هنوز روی تخته است:

MutableSharedFlow<Int>(replay = 1)
  • هر collector جدید بلافاصله آخرین مقدار را دریافت می‌کند


SharedFlow با replay = 2 (نگه‌داشتن تاریخچه رویداد)

val flow = MutableSharedFlow<Int>(replay = 2)

این یعنی:

SharedFlow دو مقدار آخر ارسال‌شده را نگه می‌دارد و به هر collector جدید پخش می‌کند.

مثال زمانی

flow.emit(1) flow.emit(2) flow.emit(3)

بافر replay:

[2, 3]

یک collector جدید:

flow.collect { println(it) }

بلافاصله دریافت می‌کند:

2 3

حالا اگر مقدار جدیدی ارسال شود:

flow.emit(4)

همه‌ی collectorهای فعال دریافت می‌کنند:

4

و بافر می‌شود:

[3, 4]

📌 این دقیقاً مثل کلاسی است که دو اسلاید آخر همیشه روی تخته باقی می‌ماند.


StateFlow؛ تخته‌ی کلاس

StateFlow نوع خاصی از Hot Flow است که می‌توان آن را به تخته‌ی کلاس تشبیه کرد:

  • همیشه دقیقاً یک مقدار فعلی دارد

  • هر کسی وارد شود، فوراً آن مقدار را می‌بیند

val stateFlow = MutableStateFlow(0)

به همین دلیل، StateFlow بهترین انتخاب برای نمایش وضعیت (State) در UI است.


چه زمانی از کدام استفاده کنیم؟

Cold Flow

  • هر مصرف‌کننده اجرای مستقل می‌خواهد

  • عملیات یک‌باره (شبکه، محاسبه)

  • نیازی به اشتراک داده نیست

SharedFlow

  • یک رویداد یا مقدار به چند بخش برنامه ارسال می‌شود

  • جلوگیری از اجرای تکراری

  • نیاز به replay رویدادها وجود دارد

StateFlow

  • نمایش وضعیت فعلی

  • UI باید فوراً آخرین مقدار را داشته باشد


جمع‌بندی نهایی

به زبان ساده:

Cold Flow می‌گوید:
«برای هر نفر، از اول توضیح می‌دم.»

Hot Flow می‌گوید:
«دارم توضیح می‌دم، هر کی هست گوش بده.»

و با replay:

«اگر دیر اومدی، چند تا از مطالب قبلی اینجاست.»

درک این تفاوت‌ها کمک می‌کند معماری تمیزتر، بهینه‌تر و قابل پیش‌بینی‌تری در برنامه‌های Kotlin و Android طراحی کنیم.

من محمد رئیسی برنامه نویس اندروید هستم و از توجهتون به ین پست سپاسگزارم.
ان شاءالله که مفید بوده باشه.

kotlin
۰
۰
محمد رئیسی
محمد رئیسی
برنامه نویس اندروید
شاید از این پست‌ها خوشتان بیاید