فلاتر کلین معماری [1]: نمای کلی و ساختار پروژه
![فلاتر کلین معماری [1]: نمای کلی و ساختار پروژه فلاتر کلین معماری [1]: نمای کلی و ساختار پروژه](https://nabfollower.com/blog/wp-content/uploads/2023/06/فلاتر-کلین-معماری-1-نمای-کلی-و-ساختار-پروژه-780x470.jpg)
This post is the first part of a tutorial series for Flutter App!.
در مراحل اولیه خود، برخی از توسعه دهندگان نرم افزار فقط برای به دست آوردن سریع مهارت های جدید و ایجاد ویژگی های کاربردی تلاش می کنند. آنها نگران نوشتن کد تمیز یا پیروی از معماری مناسب برای بهبود عملکرد برنامه نیستند. هنگام استفاده از یک فریم ورک، برخی از توسعه دهندگان دیگر اغلب از الگوی معروف MVC استفاده می کنند که به ما امکان می دهد برنامه خود را به مدل ها، نماها و کنترلرها جدا کنیم. این مشکلی در هنگام توسعه برنامه های ساده نیست، اما زمانی که ما نیاز داریم یک برنامه کاربردی را با افزودن ویژگی های جدید، به روز رسانی یک کتابخانه یا انجام کارهای مشابه، مقیاس کنیم، با تعدادی مشکل مواجه می شویم، زیرا هرچه کدهای ما همراه تر می شود، بیشتر می شود. ایجاد تغییرات در برنامه ما بدون ایجاد تغییرات متعدد در کد ما چالش برانگیز است. در نتیجه، قبل از شروع توسعه اپلیکیشن خود، ابتدا باید معماری مناسب را طراحی کنید.
هنگام طراحی معماری اپلیکیشن خود، ضروری است که به چندین اصل پاسخ دهید، از جمله:
-
جامد: پنج اصل برنامه نویسی شی گرا به خوانایی، سازگاری و قابلیت نگهداری طرح های OOP کمک می کنند.
-
بوسه: یک اصل طراحی که بیان می کند که طراحی ها و/یا سیستم ها باید تا حد امکان ساده باشند تا پذیرش و تعامل کاربر را به حداکثر برسانند.
-
خشک: یک اصل توسعه نرم افزار که مخفف عبارت “خودت را تکرار نکن” است که هدف آن کاهش تکرار کد به نفع انتزاعات و اجتناب از افزونگی است.
در سالهای اخیر، ما شاهد انواع ایدههای معماری بودهایم که اصول پیشین را اجرا میکنند، مانند:
-
معماری شش ضلعی: معماری پورت ها و آداپتورها بر اساس ایده جداسازی برنامه به اجزای جفت شده آزاد است تا منطق اصلی کسب و کار را از نگرانی های بیرونی جدا کند.
-
معماری پیاز: این معماری از چندین لایه متحدالمرکز تشکیل شده است که به هسته متصل می شود که نشان دهنده دامنه است. در واقع این معماری مبتنی بر اصل وارونگی کنترل است.
-
معماری پاک: معماری عمو باب بر اساس اصل وارونگی وابستگی برای تعیین مرزهای بین اجزای سطح بالا و سطح پایین است. علاوه بر این، این معماری تلاش می کند تا تمام معماری های قبلی را در یک ایده عملی واحد ترکیب کند.
بنابراین، همانطور که می بینیم، هدف اساسی همه این معماری ها دستیابی به یک تفکیک واضح از نگرانی ها است. این کار با تقسیم نرم افزار به لایه های مجزا انجام می شود، که معمولاً شامل یک لایه برای قوانین تجاری و لایه ای دیگر برای رابط ها می شود. علاوه بر این، هر معماری یک سیستم کاملاً تعریف شده را ایجاد می کند که عبارتند از:
1. مستقل از چارچوب.
2. قابل آزمایش
3. مستقل از UI
4. مستقل از پایگاه داده
5. مستقل از هر آژانس خارجی.
پس از بحث در مورد محبوب ترین معماری ها و نقش آنها، من برای هر برنامه فلاتر یک معماری بر اساس مفهوم عمو باب خواهم ساخت که حاوی چندین ایده معماری است.
نمودار زیر معماری پیشنهادی را با لایه های جداگانه نشان می دهد که توسط دایره ها نشان داده شده اند:
لازم به ذکر است که این معماری صرفاً یک ساختار پوشه نیست که بتوانید آن را کپی و در پروژه خود پیست کنید. این مفهوم جداسازی برنامه شما به لایه ها در حالی است که به قانون وابستگی عمو باب پایبند هستید، که بیان می کند:
هیچ چیز در یک دایره درونی نمی تواند در مورد چیزی در یک دایره بیرونی چیزی بداند.
به عبارت دیگر، هیچ متغیر، کلاس یا تابعی که در یک دایره بیرونی اعلام شده است را نمی توان در یک دایره داخلی ذکر کرد.
بیایید با ادغام این معماری در یک پروژه فلاتر شروع کنیم، زیرا تئوری فقط می تواند شما را تا اینجا پیش ببرد، و تعامل عملی جایی است که بیشتر از همه یاد می گیرید.
پروژه ای که ما ایجاد خواهیم کرد
ما یک برنامه آب و هوا ایجاد خواهیم کرد که هدف آن تجسم آب و هوای یک شهر خاص است. این اپلیکیشن دو رابط دارد: یکی برای نمایش جزئیات آب و هوای شهر و دیگری برای افزودن شهر جدید. این برنامه شامل ابتدایی ترین عملکردها مانند دریافت داده از یک API، ذخیره داده ها در پایگاه داده محلی، رسیدگی به خطاها و غیره خواهد بود:
صفحه نمایش جزئیات آب و هوا:
افزودن صفحه مورد nes city:
Flutter Clean Architecture و جریان داده
من تصمیم گرفتم همانطور که در شکل بالا مشاهده می شود از تکنیک Provider برای مدیریت حالت در این پروژه استفاده کنم. با این حال، از آنجایی که معماری پاک به هیچ روش مدیریت دولتی خاصی متصل نیست، شما آزاد هستید که یک استراتژی جایگزین را انتخاب کنید که با اولویت ها و اهداف پروژه شما مطابقت داشته باشد.
تصویر بالا همچنین جریان داده هر رویداد ایجاد شده توسط کاربر را نشان می دهد. در واقع، زمانی که یک کاربر با ویجت، اقدام آنها را به اطلاع می رسانیم ارائه دهنده کلاس، که سپس به وصل می شود useCase برای بازیابی نتیجه عمل به دنبال آن useCase با آن ارتباط برقرار می کند مخزن کلاس برای به دست آوردن راه حل از راه دور یا محلی منبع اطلاعات.
بنابراین، برای شروع پیاده سازی این لایه ها، اجازه دهید پروژه خود را به زیر پوشه ها تقسیم کنیم.
سازمان پروژه
در پوشه lib دو زیر پوشه ایجاد می کنیم. اولی به نام “هسته“، و شامل تمام اجزای مشترک و اساسی و همچنین پیاده سازی ویژگی های اصلی مانند تزریق وابستگی است. پوشه دوم با عنوان “امکانات“، و حاوی هر “ویژگی” از برنامه. به عنوان مثال، در مورد ما، ما فقط یک ویژگی داریم که اطلاعات آب و هوا را نشان می دهد و شامل دو رابط است: یکی برای جزئیات و دیگری برای افزودن شهرهای جدید. هر ویژگی نیز به سه لایه جدا می شود: داده ها، دامنه، ارائه، و کاربردها.
پوشه utils برای هر ویژگی لازم نیست. تنها زمانی مورد نیاز است که شما ابزارهای ویژه ویژگی مانند enums، کلاس ها، توابع افزونه و غیره داشته باشید.
توضیح لایه های ویژگی
– ارائه
این لایه همانطور که از نامش پیداست وظیفه ارائه اطلاعات به کاربر از طریق ویجت ها را بر عهده دارد. این لایه همچنین وظیفه گوش دادن به حالت ها و اتصال به کلاس Provider را بر عهده دارد که تمام کارها را به استفاده خاص واگذار می کند. در بیشتر موارد، وظیفه اصلی لایه ارائه، رسیدگی به اعتبارسنجی ورودی اولیه، انیمیشن ها و تعاملات کاربر است.
برای برنامه آب و هوا اعمال شد
هر رابط در مورد ما دارای دو زیرپوشه است، یکی برای فایل view و دیگری برای ویجت های آن. ما همچنین فایل ارائه دهنده را اضافه می کنیم.
– دامنه
این لایه چسب است که دو لایه دیگر را به هم متصل می کند. از اشیاء تجاری استفاده خواهد کرد (موجودیت ها) و از موارد برای پیاده سازی منطق تجاری برنامه ما استفاده کنید. علاوه بر این، هر مورد استفاده برای بازیابی داده ها به Repository متکی است.
وجود، موجودیت: قوانین کسب و کار سطح بالا در سطح سازمانی را در بر بگیرد. فقط فیلدهایی که از نظر “تجاری” معنی دارند توسط یک موجودیت نگهداری می شوند. علاوه بر این، موجودیت نتیجه نهایی است که نما از آن استفاده خواهد کرد، و کمترین احتمال را دارد که در صورت تغییرات خارجی تغییر کند. علاوه بر این، نیازی نیست که نهاد دارای فیلدهای مشابهی باشد که توسط وب سرویس بازگردانده شده است. می توانید فیلدهای خود را بر اساس نیازهای رابط کاربری خود سفارشی کنید. برای مثال، اگر مدل تماس یک قالب تاریخ مهر زمانی را برمیگرداند، موجودیت شما باید حاوی تاریخ تبدیلی باشد که تجزیه میشود.
مورد استفاده: همانطور که عمو باب اشاره کرد، مورد استفاده، “جریان داده ها را به و از موجودیت سازماندهی می کند”. یک مورد استفاده، در ابتدایی ترین شکل خود، یک اقدام کاربر مانند بازیابی اطلاعات آب و هوا بر اساس شهر، بازیابی اطلاعات آب و هوا بر اساس مختصات و غیره را نشان می دهد. برای انطباق با اصل SOLID مسئولیت واحد، هر مورد استفاده باید مستقل از موارد دیگر باشد.
لایه دامنه باید کاملا مستقل از تمام لایه های دیگر باشد. اما چگونه میتواند مستقل باشد وقتی هر موردی دادهای را از مخزن به اشتراک گذاشته شده با لایه داده بدست میآورد؟ اکنون هنر می آید وارونگی وابستگی، یکی از اصول SOLID. در واقع در لایه دامنه، یک کلاس مخزن انتزاعی ایجاد می کنیم تا قراردادی را برای کارهایی که Repository باید انجام دهد تعریف کنیم و سپس در لایه داده، اجرای واقعی آن را می نویسیم.
مخزن: یک کلاس مخزن به عنوان یک منبع منفرد از حقیقت عمل می کند و منطقی را که داده ها را بازیابی می کند و به مدل موجودیت نگاشت می کند، جدا می کند. در واقع این کلاس داده ها را از منابع مختلف (REST API، پایگاه های داده محلی، کش و غیره) جمع آوری کرده و در اختیار بقیه برنامه قرار می دهد. اجزای دیگر هیچ ایده ای ندارند که داده ها از کجا آمده اند. آنها به سادگی آن را مصرف می کنند.
برای برنامه آب و هوا اعمال شد
در مورد ما، لایه دامنه به سه لایه مجزا تقسیم می شود: موجودیت ها، قراردادهای مخزن و موارد استفاده.
– داده ها
این لایه مسئول بازیابی اطلاعات از منابع متعدد است. این شامل یک کلاس مخزن است که قرارداد دامنه را پیاده سازی می کند و تعیین می کند که آیا داده های تازه یا کش شده را برگرداند و چه زمانی آن را در حافظه پنهان نگه دارد. علاوه بر این، کلاس منبع داده، واکشی داده ها از یک منبع خاص، معمولاً یک API راه دور یا پایگاه داده محلی را کنترل می کند.
برای برنامه آب و هوا اعمال شد
سه لایه لایه داده ما را تشکیل می دهند: منابع داده، پیاده سازی مخازن و مدل ها. با توجه به این واقعیت که هر منبع داده ای آن را ارائه می دهد، ما به جای موجودیت، پوشه مدل ها را داریم. در واقع هر مدل با استفاده از روش های خاصی (از JSON، به JSON و غیره) وظیفه تبدیل داده های بدون ساختار (JSON و غیره) به اشیاء دارت را بر عهده دارد.
بعدی
پس از بررسی ساختار اپلیکیشن آب و هوا، شروع به پیاده سازی دامنه می کنیم که مستقل ترین لایه است: بعد