بازگشت به بلاگ فلاتر

معماری BLoC در عمل: چه چیزی جواب داد و چه چیزی نه

5 شهریور 1405 3 دقیقه مطالعه 565 بازدید

بعد از چهار سال ساختن اپ‌های بزرگ با BLoC، این‌ها الگوهایی هستند که در پروژه‌های واقعی دوام آوردند — و اشتباه‌هایی که دیگر تکرارشان نمی‌کنم.

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

یک Cubit برای هر واحد معنایی، نه برای هر صفحه

اشتباه رایج این است که برای هر صفحه یک BLoC بسازیم. نتیجه‌اش ده‌ها کلاس است که همه یک کار می‌کنند: یک لیست را لود می‌کنند. به‌جایش واحد را «مفهوم دامنه» بگیرید، نه «صفحه». اگر سه صفحه هر سه وضعیت کیف پول را نشان می‌دهند، یک WalletCubit کافی است.

Cubit پیش‌فرض، BLoC وقتی رویداد معنا دارد

Cubit ساده‌تر است و در بیشتر موارد کافی. سراغ BLoC کامل بروید وقتی واقعاً به جریان رویدادها نیاز دارید: debounce روی جست‌وجو، ترتیب‌دهی رویدادهای هم‌زمان، یا لاگ‌کردن دنباله‌ی کنش‌های کاربر برای دیباگ.

State باید غیرقابل‌تغییر و کامل باشد

یکی از دردناک‌ترین باگ‌هایی که دیدم از state ناقص می‌آمد: کلاس state فقط isLoading و data داشت. وقتی خطا می‌آمد، data قدیمی روی صفحه می‌ماند و کاربر فکر می‌کرد همه‌چیز درست است. state را طوری بنویسید که هر ترکیب ممکن صریح باشد.

sealed class WalletState {}
final class WalletLoading extends WalletState {}
final class WalletReady extends WalletState {
  final Balance balance;
  WalletReady(this.balance);
}
final class WalletFailed extends WalletState {
  final String message;
  WalletFailed(this.message);
}

با sealed class در Dart 3، کامپایلر مجبورتان می‌کند همه‌ی حالت‌ها را در UI هندل کنید. این تنها تغییری بود که بیشترین باگ را از ما گرفت.

لایه‌ی داده را از BLoC جدا نگه دارید

BLoC نباید بداند داده از HTTP می‌آید یا از کش. یک Repository میان آن‌ها بگذارید. سود واقعی‌اش وقتی معلوم می‌شود که بخواهید کارکرد آفلاین اضافه کنید: هیچ BLoC‌ای عوض نمی‌شود.

چه چیزی جواب نداد

تلاش برای اشتراک state بین ماژول‌ها از طریق یک GlobalBloc. در تئوری تمیز به نظر می‌رسید؛ در عمل به یک god object تبدیل شد که هر تغییری در آن نصف اپ را rebuild می‌کرد. راه‌حل بهتر: رویدادهای صریح بین ماژول‌ها و state محلی در هر ماژول.

پروژه‌ای در ذهن دارید؟

پروژه‌ای در ذهن دارید یا دنبال یک توسعه‌دهنده‌ی موبایل برای تیمتان می‌گردید؟ پیام بدهید.

همکاری با من

نوشته‌های مرتبط