این مطلب ترجمهای است از مطلب «تین مگالی» که در اینجا منتشر شده است.
وقتی برنامه پیچیدهای را توسعه میدهیم، معمولاً با چالشهایی روبرو میشویم که پیش از این خیلیها با آنها برخورد کردهاند و حالا هر کدام آنها راهحلهایی بسیار زیبا دارند. به این راهحلها «الگو» میگویند. ما معمولاً از الگوهای طراحی و الگوهای معماری میشنویم. این الگوها توسعه را آسان میکنند و بهتر است که ما هم از آنها استفاده کنیم. البته هر زمان که به استفاده از آنها نیاز باشد.
این آموزش به شما در درک اهمیت طراحی خوب پروژه و این که معماری استاندارد اندروید همیشه و برای هر کاری کافی نیست، کمک میکند. درباره چند مسأله بالقوه که ممکن است در زمان توسعه برنامههای اندروید با آنها روبرو شوید بحث میکنیم و نشان خواهم داد که برای حل آن مسائل چطور برنامه را تست کنید و قابلیت اطمینان آن را بالا ببرید. همه اینها با کمک الگوی MVP.
در این آموزش، به این موضوعات خواهیم پرداخت:
- اهمیت اجرای الگوهای معماری در پروژههای نرمافزاری
- چرا تغییر معماری استاندارد اندروید، فکر خوبی است
- مفاهیم اصلی الگوی معماری MVP
- چطور MVP با SDK اندروید سازگار میشود
در بخش اول این آموزش، بر روی مسائل نظری الگوی MVP تمرکز میکنیم و در بخش دوم به سراغ کد خواهیم رفت.
۱- معماری اندروید
طراحی برنامه موضوعی است که باید از همان ابتدا به آن توجه کرد. یکی از اولین موضوعاتی که باید آن را مد نظر قرار دهیم معماریای است که میخواهیم از آن استفاده کنیم زیرا که نحوه ارتباط اجزای مختلف پروژه با یکدیگر را تعریف میکند. همچنین قواعد پایه برای توسعه را مشخص میکند.
در کل، چارچوب (framework) یا SDK انتظار دارد که همه کارها به یک شیوه مشخص انجام شود اما همیشه این شیوهها برای پروژهها مناسب نیستند. بعضی وقتها راهی از پیش تعریف شده یا درست برای انجام کارها وجود ندارد و تصمیات طراحی را بر عهده توسعهدهنده میگذارد. SDK اندروید هم انتظار دارد که کارها به شیوه خاص خودش انجام شود اما این شیوهها یا کافی نیستند یا انتخاب درستی نیستند.
با این که اندروید، SDK فوقالعادهای دارد اما الگوهای معماری آن بسیار غیر معمول هستند و به سادگی در وسط راه توسعه جلوی شما قرار میگیرند. مخصوصاً وقتی که برنامههای پیچیدهای میسازید که نیاز به تست فراوان و نگهداری طولانی مدت دارند. خوشبختانه برای حل این مشکل راههای زیادی پیش روی ما قرار دارد.
مشکل چیست؟
سؤال خوبی است. برخی ممکن است بگویند معماری ارائه شده توسط اندروید هیچ مشکلی ندارد. این معماری کار را انجام میدهد اما آیا میشود کار را به شیوه بهتری انجام داد؟ من قویاً معتقدم که میشود.
ابزارهایی که اندروید ارائه میکند، چیدمانها، اکتیویتیها و ساختمان دادهها، به نظر میرسد که ما را به الگوی MVC راهنمایی میکنند. MVC الگویی محکم و پایدار است که هدف آن جدا کردن نقشهای متفاوت اجزای یک برنامه است. به این کار «جدا کردن نگرانیها یا موضوعات» گفته میشود.
این معماری سه لایه متفاوت ایجاد میکند:
- مدل
- ویو یا نمایشگر
- کنترلگر
هر کدام از این لایهها مسؤل بخشی از پروژه هستند. مدل به منطق کاری (Business Logic) پاسخ میدهد، نمایشگر همان رابط کاربری یا UI است و کنترلگر واسط بین نمایشگر و مدل است.
اما اگر ما با دقت معماری اندروید را بررسی کنیم، مخصوصاً ارتباط بین نمایشگر (اکتیویتیها، فرگمنتها و …) و مدل (ساختمان دادهها)، به این نتیجه میرسیم که این معماری را نمیتوان MVC دانست. این کعماری کاملاً با MVC تفاوت دارد و قوانین خاص خودش را دارد. زمانی که هدف شما ساختن بهترین برنامه است، این قوانین راه شما را سد میکنند.
اگر بخواهم دقیقتر بگویم، اگر رابطه همزیستی بین بارگیرها (loaders) و اکتیویتیها و فرگمنتها را در نظر بگیرید، میبینید که چرا باید توجه ویژهای به معماری اندروید داشته باشیم. اکتیویتی یا فرگمنت مسؤل صدا زدن بارگیر است که کار اصلی آن واکشی دادهها (از اینترنت یا دیتابیس) و برگرداندن آنها به والد خودش است. وجود بارگیر شدیداً به والدش گره خورده است و هیچ جدایی بین نقش نمایشگر (اکتیویتی/فرگمنت) و منطق کاری که توسط بارگیر انجام میشود وجود ندارد.
در برنامهای که دادهها (بارگیر) این چنین محکم به نمایشگر چسبیده است چطور میتوانیم تست واحد (Unit Test) انجام دهیم/ اساس تست واحد بر روی انجام تست بر روی کوچکترین بخش کدهای ممکن است. اگر در یک تیم کار میکنید و باید چیزی را تغییر دهید که در کد یک نفر دیگر قرار دارد، چطور میتوانید مسأله را پیدا کنید؟ اگر پروژه هیچ الگوی معماری مشخص نداشته باشد، اصطلاحاً همه چیز میتواند همه جا باشد.
راهحل چیست؟
این مشکل را میتوانیم با پیادهسازی یک الگوی معماری متفاوت حل کنیم و خوشبختانه SDK اندروید اجازه این کار را به ما میدهد. ما میتوانیم از بین راهحلها، آنهایی را انتخاب کنیم که برای اندروید مناسبتر است. الگوی MVC انتخاب خوبی است اما یک الگوی بسیار نزدیک به آن به نام MVP یا Model-View-Presenter انتخاب بهتری است. MVP بر روی اصولی سبیه MVC توسعه یافته است اما رویکرد مدرنتری دارد و «جدا کردن نگرانیها یا موضوعات» را بهتر انجام میدهد و امکان اجرای تست روی برنامه را به حداکثر میرساند.
اگر به معماری اندروید دقت کنیم میبینیم که
- اندروید به هیچ وجه اهمیتی به جدایی موضوعات نمیدهد
- بهتر است کاری به معماری اندروید نداشته باشیم و آن را رها کنیم زیرا در آینده برای ما مشکل ساز خواهد شد
- فقدان یک معماری مناسب، تست واحد را به یک رنج و عذاب واقعی تبدیل میکند
- اندروید به ما اجازه میدهد که از بین چند الگوی معماری متفاوت یکی را انتخاب کنیم
- الگوی MVP یکی از بهترین راهحلها برای اندروید است
۲- الگوی MVP در اندروید
همانطور که پیش از این گفتم، اندروید در زمینه جدایی موضوعات بسیار ضعیف است. خوشبختانه الگوی MVP این ضعف را جبران میکند. MVP برنامه را به سه لایه اصلی تقسیم میکند:
- مدل (Model)
- نمایشگر (View)
- معرف (Presenter)
هر کدام از این لایه مسؤلیت خاصی دارند و ارتباط بین این لایهها از طریق «معرف» یا Presenter انجام میشود. معرف نقش واسطه را بین اجزای مختلف بر عهده دارد.
- مدل منطق کاری برنامه را بر عهده دارد. نحوه ایجاد دادهها، دخیرهسازی و تغییرات دادهها را کنترل میکند.
- نمایشگر یک رابط منفعل است که دادهها را نمایش میدهد و عملیات کاربر را به «معرف» هدایت میکند.
- معرف (Presenter) نقش میانجی را دارد. دادهها را از مدل میگیرد و آنها را دز نمایشگر نشان میدهد و همچنین عملیات کاربر که از سمت نمایشگر میآید را پردازش میکند.
تفاوت بین MVP و MVC
الگوی MVP از روی MVC ساخته شده است. از آنجایی که آنها مفاهیم مشترک بسیار زیادی با هم دارند، بیان تفاوتهای آنها با هم سخت است. کنترلگر و معرف هر دو نقشهایی شبیه به هم دارند. نقش آنها ایجاد ارتباط بین مدل و نمایشگر است. میتوان گفت که کنترلگر در مدیریت مدل و نمایشگر به اندازه «معرف» قدرت ندارد.
در الگوی MVC لایه نمایشگر به نوعی هوشمند حساب میشود و میتواند دادهها را مستقیماً از مدل استخراج کند. در الگوی MVP نمایشگر کاملاً منفعل است و همیشه دادهها از طریق معرف به نمایشگر فرستاده میشود. کنترلگر در MVC میتواند به طور مشترک بیت چند نمایشگر به اشتراک گذاشته شود (چند نمایشگر از یک کنتلگر استفاده کنند) در حالی که در MVP رابطه بین نمایشگر و معرف یک رابطه یک به یک است. بنابراین معرف فقط به یک نمایشگر وصل میشود.
بنابراین در MVP:
- نمایشگر نمیتواند به مدل دسترسی داشته باشد
- معرف فقط به یک نمایشگر وصل میشود
- نمایشگر کاملا منفعل است
این تفاوتهای معنایی باعث میشود الگوی MVP جدایی موضوعات بهتری را تضمین کندو نیز امکان تست برنامه را بسیار افزایش دهد.
اکتیویتی، فرگمنت و اشیای نمایشگر
چند تفسیر متفاوت از چگونگی پسادهسازی MVP در اندروید وجود دارد. به صورت کلی اکتیویتیها و فرگمنتها نقش نمایشگر را بر عهده دارند و مسئولیت ایجاد معرف و مدل بر عهده آنها است. نمایشگر همچنین مسئول نگهداری معرف و مدل در زمان تغییر آنها و اطلاعرسانی به آنها درباره نابودی احتمالی نمایشگر است.
سایر اشیای نمایشگر (ویو) مانند RecyclerView ممکن است به عنوان بخشی از نمایشگر در MVP حساب شوند. یک رابطه یک به یک بین نمایشگر و معرف وجود دارد که در بعضی از شرایط خیلی پیچیده ممکن است برای یک نمایشگر نیاز به چند معرف باشد.
آنچه تا الان آموختیم
با استفاده از الگوهای طراحی و معماری، میتوانیم فرایند توسعه را آسان و شفاف کنیم.
- اندروید فاقد یک الگوی معماری ساخت یافته است.
- بدون استفاده از الگوی طراحی پایدار ممکن است در طول راه به مشکلاتی برخورد کنیم، مخصوصاً مشکلات مربوط به تست شوندگی و نگهداری از برنامه.
- الگوی Model View Presenter باعث افزایش جدایی موضوعات متفاوت میشود و تست شوندگی برنامه را تسهیل میکند.
- معرف یا Presenter واسطه ارتباط بین نمایشگر و مدل است.
- مسئولیت منطق کاری برنامه با مدل است.
- نقش نمایشگر را بیشتر اوقات اکتیویتی یا فرگمنت بر عهده دارند.
مؤخره
در بخش بعدی این مطلب ما الگوی MVP را در یک برنامه اندروید پیادهسازی خواهیم کرد و مفاهیمی که آحوختیم را میآزماییم و پیچیدگیهای این الگو را در اندروید بررسی میکنیم.
در انتهای این دوره میتوانید از MVP در پروژههای خود استفاده کنید، چهارچوب خودتان را بسازید یا از راهحلهای شناخته شده دیگر استفاده کنید. امیدوارم تا انتهای این مطالب من را دنبال کنید.
سلام
بسیار عالی، منتظر قسمت های بعدی مقاله هستم
ممنون از شما
واقعا عالیه، خیلی ممنون که این بحث رو دارید توضیح می دین. بی صبرانه منتظر آموزش بعدی هستم دمتون گرم.
خیلی خوب.ممنون از مطالب عالی شما
ممنون از این مطالب
بهترین مطالبی بود که در اینباره خوندم
بسیار عالی بود
ممنونم
هنوز ادامشو نذاشتید تو سایت؟
اااوم این چیزی که من برداشت کردم ینی با mvp باید بیشتر از mvc کد نوشت
مخصوصا اونجاش که گفت در شرایطی باید چند تا پرزنتر برای نمایشگر ساخت 🙁
بعدشم تنها مزینش تست برنامه قبل از آماده شدن view هست ؟
درسته؟