پیاده سازی معماری MVVM در اندروید با استفاده از ViewModel و LiveData

در این مقاله قصد دارم به آموزش معماری MVVM در اندروید بپردازم. گوگل در سال ۲۰۱۷ دو کامپوننت به نامهای LiveData و  ViewModel رو ارائه داد که با استفاده از آنها پیاده سازی معماری MVVM بسیار آسان خواهد شد. در این مقاله ابتدا نگاه کوتاهی به معماری MVP میاندازیم. در ادامه بیان میکنیم که چرا این معماری مناسب نیست و به جای آن باید از معماری MVVM استفاده کرد. پس از مطالعه این مقاله شما جواب سوالهای زیر را خواهید دانست.

  • معماری MVP چه مشکلاتی دارد و چرا ما باید به جای MVP از MVVM استفاده کنیم؟
  • چطور با استفاده از LiveData و ViewModel میتوانیم معماری MVVM رو به راحتی پیاده سازی کنیم؟

معرفی معماری MVP

یکی از معماری هایی(Architecture) که برای توسعه اپ اندروید استفاده میشه معماری MVP است. این سه حرف مخفف Model View Presenter هستند. در ادامه معماری MVP رو با ذکر یک مثال توضیح میدم. فرض کنید میخواهیم در اپ یک activity داشته باشیم که لیست فیلم های در حال اکران رو از بک-اند بگیره و نمایش بده. اسم این activity رو MovieActivity میزاریم. در معماری MVP ما ۲ تا اینترفیس باید داشته باشیم یکی برای View و یکی هم برای Presenter. اسم اونها رو به ترتیب MovieView و MoviePresenter میزاریم. یک کللاس هم باید داشته باشیم که اینترفیس Presenter رو پیاده سازی(Implement) کنه اسم این کلاس را هم MoviePresenterImpl میزاریم. در شکل زیر استفاده از معماری MVP برای MovieActivity نشان داده شده است.

همانطور که در شکل مشخص است کلاس MoviePresenterImpl از اینترفیس MovieView برای ارتباط با activity استفاده میکند. یکی از عیب های مهم معماری MVP این است که Presenter ارتباط تنگاتنگی با View دارد و اون طور که باید مستقل نیست تا بتوان به راحتی براش تست نوشت. 

استفاده از معماری MVVM به جای MVP

برای برطرف کردن مشکلی که در بخش قبل عنوان کردیم اندروید معماری جدیدی را تحت عنوان MVVM معرفی کرده است. این حروف مخفف Model View ViewModel هستند. برای پیاده سازی این معماری اندروید دو تا کامپوننت به نامهای LiveData و ViewModel را معرفی کرده است.

پیاده سازی معماری MVVM با استفاده از ViewModel و LiveData نه تنها باعث میشه مشکل ارتباط تنگاتنگ Presenter و View که در MVP وجود داشت برطرف بشه بلکه باعث میشه دیتایی که اکتیویتی بهش نیاز داره به چرخه زندگی اکتیویتی وابسته نباشه و با از بین رفتن اکتیویتی از بین نره. به عبارت دیگه وقتی برای اولین بار اکتیویتی ساخته میشه و دیتای مورد نیازش از بک-اند گرفته میشه این دیتا تا زمانی که اپلیکیشن بسته نشده کش میشه و برای مثال اگه کاربر گوشی رو بچرخونه و اپ در حالت افقی نمایش داده بشه از همون دیتایی که قبلا گرفته شده استفاده میشه و دیتای جدیدی از بک-اند گرفته نمیشه.

پیاده سازی MVVM با استفاده از ViewModel و LiveData

برای استفاده از ViewModel و LiveData در اپ باید ابتدا آخرین ورژن android.arch.lifecycle:extensions را به گریدل پروژه اضافه کنید. پیاده سازی MovieActivity با استفاده از معماری MVVM به صورت شکل زیر خواهد بود.

 در معماری MVP ما ۲ تا اینترفیس داشتیم با ۲ تا کلاس ولی در معماری MVVM فقط ۲ تا کلاس داریم که ارتباط تنگاتنگی هم با هم ندارند و راحتتر میتوان برایشان تست نوشت. برای استفاده از کلاس MovieViewModel داخل اکتیویتی ابتدا باید یک نمونه از کلاس MovieViewModel درست کنید. برای اینکار از ViewModelProviders استفاده کنید. این کلاس یه سری متدهای static دارد که از آنها میتوان برای ایجاد ViewModel ها استفاده کرد. این کلاس خودش هندل میکند که اگر قبلا نمونه ای از ViewModel وجود داشته باشد همان را برمیگرداند وگرنه یک نمونه جدید ازش درست میکنه. یه شبه کدی از کلاس MovieViewModel در زیر نشان داده شده است.

همانطور که در شکل مشخص است متد getMovies یه آبجکتی از نوع LiveData برمیگردونه. برای گرفتن فیلم ها و نمایش آنها در MovieActivity از کد زیر استفاده میکنیم.

 

LiveData یه متدی به اسم observe دارد. این متد به صورت reactive صدا زده میشود. یعنی وقتی دیتای برگشتی آماده شده متد onChanged صدا زده میشود. در متد onChanged میتوانیم دیتای برگردانده شده را جهت نمایش در recyclerView استفاده کنیم.

درباره نویسنده

پست های مرتبط

7 نظر

  1. سید محمد رضا امامیان

    با سلام و خسته نباشید و تشکر خدمت خانم قاسمی.
    یک سوال داشتم…
    من دو سالی هست که اندروید کار میکنم اما متاسفانه هنوز وارد معماری ها نشدم و اطلاعات بیسی ندارم ازشون.
    خواستم ببینم از کجا شروع کنم به یادگیری معماری ها و این که معماری ها چی هستن اصلن؟

    پاسخ
    1. فهیمه قاسمی
      فهیمه قاسمی

      سلام خوشحالم که از آموزش های سایت استفاده کردین. معماری رو اگه بخوام خیلی خلاصه اینجا براتون بگم به این صورت است که شما وقتی میخواید برنامه نویسی کنین بر طبق تجربه ای که برنامه نویس ها در مدتها به دست آوردن توصیه هایی رو به شما میکنن که یکی از این توصیه ها شکل دادن به برنامتون براساس یه معماری خاص است. هر برنامه بخش های مختلفی داره که معمولا بین بیشتر اپ ها این بخش ها مشترکه. مثلا برنامه هایی که از API برای ارتباط با بک اند استفاده میکنند همه باید یه بخشی رو برای اینکار داشته باشن یا برنامه هایی که اطلاعاتی رو در پایگاه داده ذخیره میکنند هم به همین شکل باید یه بخشی رو برای اینکار داشته باشند. حالا هر معماری به شما میگه که چطوری این بخش هارو توی برنامتون اضافه کنین که کدتون از لحاظ ساختار اوکی باشه. یعنی کدهای شما هم راحت قابل خوندن و فهم باشند و هم عیب یابیشون راحت تر باشه و هم تست نوشتن براشون راحت تر باشه و …
      شما موقعی که تازه برنامه نویسی رو شروع کردین طبیعیه که درکی از ضرورت استفاده از معماری ها نداشته باشین. توی ویدیو آموزشی rxjava من اول اپ رو بدون استفاده از معماری خاصی نوشتم و بعد اون رو تبدیل به معماری MVP کردم که میتونین از اون ویدیو هم برای آموزش استفاده کنین.

      پاسخ
  2. رضا

    سلام من یه سوال در مورد ساخت کلاس repository تو معماری mvvm دارم.میدونم وقتی که داریم از دیتابیس استفاده میکنیم به ازای هر موجودیت یک repository باید ساخته بشه تا logic رو توش پیاده سازی کنیم.اما من دارم یه فروشگاه اینترنتی مینویسم و موردی که برام پیش اومده به این صورته:من چند تا activity دارم که توی اونها چندین spinner وجود داره که اطلاعات این spinner ها از سرور میاد(یعنی من باید چند تا درخواست با رتروفیت بزنم تا اطلاعات رو از سرور دریافت کنم و توی اسپینرها نمایش بدم) و بعدش وقتی که کاربر انتخاب هاشو از طریق اسپینرها انجام داد, و مثلا روی دکمه ثبت خرید کلیک کرد,این اطلاعات داخل یه مدل set میشه و یه درخواست خرید میره سمت سرور.حالا سوال من به این شکله:من بعضی از این اسپینرها رو توی activity های دیگه هم دارم,خب حالا تکلیف چیه؟من باید برای هر activity یه repository بسازم و درخواست های سمت سرورم رو توش بزنم یا فقط یه repository داشته باشم ؟(میدونم که به ازای هر view ما یک viewmodel داریم و در مورد repository اینطور نیست اما خب الان باید چه کنم؟اگر فقط یه repository داشته باشم این repository بزرگ و بزرگتر میشه وغیرقابل مدیریت)

    پاسخ
    1. فهیمه قاسمی
      فهیمه قاسمی

      سلام بابت تاخیر عذرخواهی میکنم. خب وقتی یک repository رو چند جا لازم دارین یکی ازش بسازید و جاهای دیگه هم استفاده کنین دلیل نداره به ازای هر view یک repository جدا بسازین

      پاسخ

پاسخ

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

شش + 12 =