فلاتر آزادی زیادی در زمینه کارهایی که می‌توان انجام داد فراهم ساخته است. البته برخی اوقات مانند زمانی که تازه شروع به کار کرده‌اید، این آزادی می‌تواند یک عیب باشد. این نکته به طور خاص در مورد مدیریت حالت (State) و معماری اپلیکیشن صدق می‌کند. در این مقاله با مفاهیم معماری اپلیکیشن فلاتر آشنا خواهیم شد.

برخی توسعه‌دهندگان جامعه فلاتر کارهای خوبی در زمینه طراحی مدل سازماندهی اپلیکیشن‌های فلاتر انجام داده‌اند. اما درک این مدل‌ها برای افراد مبتدی کمی دشوار است. در این راهنما کوشش می‌کنیم درکی سطح بالا از شیوه معماری اپلیکیشن فلاتر ارائه کرده و نوعی راهنمای عملی در مورد استفاده از پکیج Provider Architecture در اختیار مخاطبان عزیز قرار دهیم.

مقدمه‌ای بر Provider

FilledStacks از یک معماری به سبک MVVM بهره می‌گیرد. در این معماری «نما» (View) معمولاً یک لی‌آوت ویجت برای یک صفحه از اپلیکیشن است. این نما شامل هیچ منطق یا حالتی نیست و در «مدل نما» (View Model) جای گرفته است که از هیچ کدام از جزییات نما آگاهی ندارد. اغلب اپلیکیشن ها نیاز دارند به داده‌ها دسترسی داشته باشند و آن‌ها را ذخیره سازند و این کار توسط سرویس‌ها انجام می‌یابد که در عمل همان کلاس‌های دارت (Dart) محسوب می‌شوند و اطلاعی از جزییات امور ندارند. به همین جهت مدل‌های نما لازم نیست در مورد شیوه انجام کار دغدغه‌ای داشته باشند.

معماری اپلیکیشن فلاترما برای هر صفحه روی اپلیکیشن یک مدل نما ایجاد می‌کنیم. سرویس‌ها به صورت سراسری در دسترس ما هستند و از این رو بدون تغییر باقی می‌مانند. یک اپلیکیشن چندصفحه‌ای ساختاری مانند زیر خواهد داشت:

معماری اپلیکیشن فلاتر

به بیان عملی فایل‌ها می‌توانند به صورت زیر سازماندهی شوند:

معماری اپلیکیشن فلاتر

البته استفاده از هر سازماندهی دیگری نیز آزاد است. FilledStacks معمولاً مدل‌های نما را در پوشه core قرار می‌دهد. شاید شما ترجیح بدهید آن‌ها را به نماهایی که از آن‌ها استفاده می‌کنند نزدیک‌تر قرار دهید، اما به نظر می‌رسد آن سازماندهی که FilledStacks استفاده می‌کند، بهتر است.

مثال

اکنون یک مثال ساده را بررسی می‌کنیم تا معماری فوق را پیاده‌سازی کنیم. در ادامه با شیوه ایجاد یک نما و مدل نمای مرتبط با آن آشنا می‌شویم. پیشنهاد می‌کنیم روی این مثال وقت بگذارید و به جای مطالعه صرف، آن را عملاً پیاده‌سازی کنید. بدین ترتیب درک بهتری از مفاهیم به دست می‌آورید.

شروع

یک پروژه جدید آغاز کنید. هر نامی که دوست دارید برای آن بگذارید. یک اپلیکیشن شمارنده پیش‌فرض به دست می‌آورید که در ادامه آن را با سبک معماری MVVM با استفاده از Provider Architecture پکیج ویرایش خواهیم کرد.

پکیج provider_architecture را به فایل pubspec.yaml اضافه کنید:

نکته: ما عملاً نیازی نداریم که از پکیج Provider Architecture استفاده کنیم تا این الگوی معماری را پیاده‌سازی نماییم. اما این کار مزیت‌های دیگری از قبیل حذف برخی کدهای آماده و همچنین پنهان‌سازی برخی از پیچیدگی‌های پکیج Provider را دارد که به صورت درونی مورد استفاده قرار می‌گیرد.

در این مثال قصد نداریم ساختار پوشه کاملی که در بخش قبل دیدیم را ایجاد کنیم، اما اگر شما تمایل داشته باشید، می‌توانید چنین کنید.

مدل نما

در پوشه /lib یک فایل جدید به نام counter_viewmodel.dart ایجاد کنید. سپس کد زیر را در آن قرار دهید

توجه داشته باشید که این کلاس ChangeNotifier را بسط می‌دهد که متد ()notifyListeners را در اختیار ما قرار می‌دهد. این نما یک شنونده خواهد بود و از این رو این متد آن چیزی است که پکیج Provider Architecture برای ساخت مجدد UI در موارد بروز تغییر مورد استفاده قرار می‌دهد. ChangeNotifier بخشی از foundation در فلاتر محسوب می‌شود و از این رو عملاً هیچ وابستگی به پکیج‌های provider_architecture یا provider در مدل نما ندارد.

نما

یک فایل جدید به نام counter_screen.dart در پوشه /lib ایجاد کنید. این همان لی‌آوت ویجت UI برای صفحه counter است. کد زیر را در آن وارد کنید:

ViewModelProvider را در ابتدای متد build()‎ می‌بینید. این همان چیزی است که CounterViewModel در اختیار درخت ویجت قرار داده است. از آنجا که «حالت» (State) در مدل نما قرار دارد، نیازی به استفاده از یک «ویجت باحالت» (StatefulWidget) وجود ندارد. از این رو می‌بینید که CounterScreen یک StatelessWidget است. این صفحه یک مدل نما می‌گیرد. زمانی که دکمه فشرده شود این صفحه متد ()increment را روی مدل نما فراخوانی خواهد کرد که به نوبه خود موجب تحریک یک بازسازی با مقدار counter جدید می‌شود.

همچنین باید main.dart را پاک‌سازی کنیم. کد آن را به صورت زیر جایگزین کنید:

اکنون اگر اپلیکیشن را اجرا کنید، باید دقیقاً همانند اپلیکیشن پیش‌فرض شمارنده رفتار کند.

معماری اپلیکیشن فلاتر

مزیت استفاده از پکیج Provider Architecture

تا به اینجا هر کاری انجام دادیم، با استفاده از پکیج Provider قدیمی و با بهره‌گیری از یک ChangeNotifierProvider و یک Consumer نیز قابل انجام بود. اما یکی از نیازهای رایج، واکشی برخی داده‌های اولیه از شبکه و یا یک پایگاه است. مدل نمای شما می‌تواند یک متد عرضه کند که این وظایف اولیه را انجام می‌دهد.

کد موجود در فایل counter_viewmodel.dart را با کد زیر عوض کنید:

چنان که می‌بینید، اکنون متدی برای واکشی برخی داده‌های اولیه از یک سرویس web API وجود دارد. در این نوشته قصد نداریم در مورد روش ایجاد یک سرویس صحبت کنیم، از این رو صرفاً یک کد ساختگی در انتها قرار می‌دهیم.

نکته مهم در مورد پکیج Provider Architecture این است که ViewModelProvider یک callback به نام onModelReady دارد که به ما امکان می‌دهد تا برخی کدهای اولیه را در زمانی که مدل نما آماده شده است اجرا کنیم.

در فایل counter_screen.dart آرگومان زیر را به ViewModelProvider اضافه کنید:

اینک زمانی که اپلیکیشن را اجرا کنید، پس از این که ویژگی دوثانیه‌ای تکمیل شد به صورت خودکار به‌روزرسانی می‌شود.

معماری اپلیکیشن فلاتر

جمع‌بندی

در این بخش راهنمایی برای آشنایی با شیوه راه‌اندازی سریع آن در پروژه‌ها ارائه می‌کنیم.

وابستگی

وابستگی provider_architecture را به فایل pubspect.yaml اضافه کنید:

مدل نما

فایل جدیدی به نام my_screen_viewmodel.dart ایجاد کرده و یک کلاس دارت به آن اضافه کنید که ChangeNotifier را بسط دهد:

نما

فایل جدیدی به نام my_screen.dart ایجاد کرده و لی‌آوت ویجت نرمال خود را برای آن صفحه بسازید.

یک ViewModelProvider به ابتدای درخت ویجت MyScreen خود اضافه کنید. آسان‌ترین روش برای انجام این کار استفاده از یک میانبر برای قرار دادن ویجت فوقانی درون یک ویجت جدید است. با این حال، به جای این که یک child داشته باشید از => برای بازگشت دادن ویجت فوقانی از پارامتر builder استفاده کنید.

سپس درون درخت ویجت می‌توانید به مدل نما به صورت زیر دسترسی داشته باشید:

  • model.someValue
  • model.doSomething()

سخن پایانی

در این مقاله با معماری مقدماتی یک اپلیکیشن فلاتر آشنا شدیم. در زمانی که از پکیج Provider Architecture استفاده می‌کنید، برخی نیازهای دیگر هم وجود دارند که با آن‌ها مواجه خواهید شد. برای کسب اطلاعات بیشتر در این خصوص پیشنهاد می‌کنیم از مستدات (+) آن بهره بگیرید. با این حال توضیحاتی که در این راهنما ارائه شده‌اند برای شروع کار کافی هستند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

میثم لطفی (+)

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

بر اساس رای 6 نفر

آیا این مطلب برای شما مفید بود؟

2 نظر در “معماری اپلیکیشن فلاتر — راهنمای مقدماتی

  • مرسی از میثم خان لطفی عزیز در همه زمینه ها مقاله های فوق العاده شما خیلی بهم کمک کردن

    فقط یه سوال دارم این معماری در پروژه های بزرگ مشگل ساز نیست؟
    میشه بجای الگو های پیچیده مثل bloc وredux استفاده کرد.؟

    1. سلام و وقت بخیر دوست عزیز؛
      از ابراز لطف شما متشکرم. روش‌های مدیریت حالت در فلاتر زیاد هستند و هر کدام برای موقعیت‌های مشخصی مناسب هستند. به طور کلی پکیج پرُوایدر برای اپلیکیشن‌های ساده مناسب است و برای موارد پیچیده‌تر بهتر است از BLoC و Redux استفاده شود.
      از توجه شما سپاسگزارم.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *