tejariapp-new-logotejariapp-new-logotejariapp-new-logotejariapp-new-logo
  • صفحه اصلی
  • پروژه ها
    • پروژه طراحی سایت
    • پروژه های اندروید
    • پروژه های تحت ویندوز
    • UI & UX
    • ربات تلگرام
  • سفارش پروژه
    • انجام پروژه اندروید (Android)
    • طراحی و ساخت اپلیکیشن موبایل
    • انجام پروژه طراحی سایت با php
    • انجام پروژه طراحی سایت با Asp.net
    • انجام پروژه سی شارپ
    • فرم سفارش پروژه
  • مدرسه ی تجاری اپ
    • طراحی سایت
    • اندروید
    • سی شارپ
    • آموزش پایگاه داده
    • برنامه های کاربردی
  • لینک های مفید
    • پرداخت آنلاین
    • درباره تجاری اپ
    • تماس با ما
استخدام برنامه نویس متلب
سفارش پروژه
✕
            هیچ نتیجه ای یافت نشدمشاهده همه نتایج

            مقایسه دو معماری MVP و MVVM در اندروید با مثال

            • صفحه نخست
            • مدرسه ی تجاری اپ آموزش اندروید
            • مقایسه دو معماری MVP و MVVM در اندروید با مثال
            دانلود UI Kit اپلیکیشن یادآور اندروید بر پایه متریال دیزاین
            دانلود UI Kit اپلیکیشن یادآور اندروید بر پایه متریال دیزاین
            20 اردیبهشت 1400
            سورس اندروید اپلیکیشن نوبت دهی پزشک آنلاین
            سورس اندروید اپلیکیشن نوبت دهی پزشک آنلاین
            28 اردیبهشت 1400
            منتشر شده توسط مهندس داودی
            مقایسه دو معماری MVP و MVVM در اندروید با مثال

            مقایسه دو معماری MVP و MVVM در اندروید با مثال

            مقایسه دو معماری MVP و MVVM در اندروید موضوعی است که در این مقاله به آن می پردازیم. این روز ها دو الگوی طراحی یا دیزاین پترن Design pattern اصلی در دنیای برنامه نویسی اندروید وجود دارند، MVP و MVVM. در این مقاله به تفاوت ها و شباهت های معماری MVP و MVVM می پردازیم.

            مقایسه دو معماری MVP و MVVM در اندروید با مثال

            هر دو دیزاین پترن Design Pattern سیستم را به سه قسمت اصلی: Model , View و Controller تقسیم می کنند. نکته جالب در رابطه با این دو Design Pattern اندروید این است که، ممکن است کسی که تجربه کار با هر دو را نداشته باشد، نتواند تفاوت این دو الگوی طراحی اندروید را تشخیص دهد.

            مقایسه بخش های Model , View و Controller

            بخش Model در هر دو Design Pattern یکسان است و تفاوتی ندارد. به دو بخش دیگر می پردازیم که شامل View و Presenter در MVP و View و ViewModel در MVVM هستند.

            مقایسه دو معماری MVP و MVVM در اندروید
            مقایسه MVP و MVVM در اندروید

            مهم ترین تفاوت بین این دو معماری، نبود فلش برگشت از ViewModel به View در MVVM می باشد.(تصویر بالا)

            در MVP نقش Presenter ارائه دهنده تغییرات به View است و همچنین، دریافت کننده داده برای تکمیل عملیات می باشد. در MVVM اما، شاهد تفاوت بزرگی با MVP هستیم. ViewModel فقط و فقط وظیفه فراهم کردن داده را دارد در حالیکه View تنها داده ها را مصرف می کند.

            حتی اگر View وظیفه تصمیم گیری درباره نحوه مصرف داده را به عهده داشته باشد، به این معنی نسیت که باید شامل پیاده سازی منطق پیچیده ای درون خود باشد. به عبارتی می توان گفت ایده ViewModel از ابتدا این بود که تنها داده را برای View آماده کند و از آن سو View داده را بدون انجام هیچ عملیات سخت و پیچیده ای نمایش دهد.

            ViewModel می تواند عملیات منطقی و پیچیده بر روی داده های ورودی کاربر اعمال کند اما View تنها وظیفه گرفتن داده و نمایش آن را به عهده خواهد داشت.

            در ادامه مقایسه MVP و MVVM را در قالب مثال های مختلف انجام خواهیم کرد.

            مثال 1: استفاده از MVP – مقدار دهی TextView توسط Presenter

            در مثال زیر از معماریMVP استفاده شده است و هدف آن مقدار دهی TextView توسط Presenter می باشد.

            class MainPresenter(private val view: MainView) {
            	
            
            	    fun setupView() {
            	        view.changeText("Hello World!")
            	    }
            	
            
            	    interface MainView {
            	        fun changeText(textValue: String)
            	    }
            	}
            	
            
            	class MainActivity : AppCompatActivity(), MainPresenter.MainView {
            	
            
            	    private val presenter = MainPresenter(this)
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	
            
            	        presenter.setupView()
            	    }
            	
            
            	    override fun changeText(textValue: String) {
            	        helloTextView.text = textValue
            	    }
            	}
            
            

            به دو نکته مهم در مثال فوق دقت کنید:

            • Presenter واسط یا interface با نام MainView را تعریف می کند که توسط Activity نیز implement یا پیاده شده است.
            • Presenter تصمیم می گیرد که چه زمانی UI باید تغییر کند.

            همچنین بخوانید: معماری mvp در اندروید با کاتلین

            مثال 2: استفاده از MVVM – مقدار دهی TextView توسط Presenter

            معادل کد فوق را با MVVM به صورت زیر پیاده می کنیم.

            class MainViewModel {
            	
            
            	    val textValue = "Hello World!"
            	}
            	
            
            	class MainActivity : AppCompatActivity() {
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	
            
            	        val viewModel = MainViewModel()
            	        helloTextView.text = viewModel.textValue
            	    }
            	}
            
            

            همانطور که می بینید، وظیفه View است که تصمیم بگیرید چه زمانی از داده ای که درون ViewModel وجود دارد استفاده کند. اگر دقت کرده باشید دیگر نیازی به پیاده سازی یک واسط یا interface نداریم. که این امر به معنی کم تر شدن هرچه بیشتر کدها و بوجود آمدن خوانایی بیشتر است.

            مقایسه MVP و MVVM از لحاظ استقلال در کد ها

            در MVVM ما استقلال بیشتری در کدها خواهیم داشت، این جمله به چه معناست؟ از آنجا که ViewModel دیگر اتصالی به View ندارد پس استقلال بیشتری دارد و وابستگی کمتری در کدها بوجود آمده است. این امر باعث می شود بتوانیم تغییرات بیشتری را در UI بدون نیاز به اعمال تغییر در لایه های منطقی کار، بوجود بیاوریم.

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

            یکی از راه حل های ارائه شده توسط MVP این است که از RxJava برای مدیریت چرخه حیات Activity یا Fragment استفاده کنیم که کار دشواری است.

            همچنین بخوانید: کتابخانه RxJava را کاربردی بیاموزیم

            مثال 3: استفاده از Dependency Injection برای دریافت نمونه ای از Presenter در

            بیایید با مثال به این موضوع بپردازیم.

            class MainPresenter @Inject constructor(private val service: WorldService) {
            	
            
            	    private var view: MainView? = null
            	    private var disposable: Disposable? = null
            	
            
            	    fun onButtonClicked() {
            	        view?.changeProgressVisibility(View.VISIBLE)
            	        disposable = service.requestHello()
            	                .subscribeOn(Schedulers.io())
            	                .observeOn(AndroidSchedulers.mainThread())
            	                .subscribe(this::onServiceResponse)
            	    }
            	
            
            	    fun bind(view: MainView) {
            	        this.view = view
            	    }
            	
            
            	    fun unbind() {
            	        disposable?.dispose()
            	        this.view = null
            	    }
            	
            
            	    private fun onServiceResponse(response: String) {
            	        view?.changeProgressVisibility(View.GONE)
            	        view?.changeText(response)
            	    }
            	
            
            	    interface MainView {
            	        fun changeText(textValue: String)
            	        fun changeProgressVisibility(visibility: Int)
            	    }
            	}
            	
            
            	class MainActivity : AppCompatActivity(), MainPresenter.MainView {
            	
            
            	    @Inject lateinit var presenter: MainPresenter
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	        Dependencies.inject(this)
            	
            
            	        button.setOnClickListener { presenter.onButtonClicked() }
            	    }
            	
            
            	    override fun onStart() {
            	        super.onStart()
            	        presenter.bind(this)
            	    }
            	
            
            	    override fun onSaveInstanceState(outState: Bundle?) {
            	        super.onSaveInstanceState(outState)
            	        presenter.unbind()
            	    }
            	
            
            	    override fun changeText(textValue: String) {
            	        helloTextView.text = textValue
            	    }
            	
            
            	    override fun changeProgressVisibility(visibility: Int) {
            	        progressBar.visibility = visibility
            	    }
            	}
            
            

            در این مثال ما از Dependency Injection برای دریافت نمونه ای از Presenter استفاده کردیم. به علاوه برای جلوگیری از بوجود آمدن leak در View توسط presenter باید دستورات لازم را بنویسیم. (کتابخانه هایی برای انجام این کار در معماری MVP ارائه داده شده اند.)

            زمان کلیک بر روی Button، Presenter مجددا در پس زمینه و به صورت asynchronous برای انجام عملیات خاصی ایجاد می شود و همچنین منتظر response خواهد ماند چرا که زمان دریافت response، اقدام به آمدن به thread اصلی برای نمایش response در UI می کند. مگر اینکه کاربر پیش از دریافت موفق ریسپانس اقدام به خروج از Activity جاری بکند که به همین خاطر است که ما هم دستور   presenter.unbind() را در onSaveInstanceState() نوشته ایم که کرشی اتفاق نیافتد و تنها حرکت کاربر بین صفحات و یا خروج کاربر از صفحه انجام شود.

            نکته دیگری که باید زمان پیاده سازی MVP به آن دقت کنیم، lifecycle-aware بودن کلاس هاست که کد های boilerplate زیادی را به دستورات ما اضافه می کند.

            خوشبختانه گوگل راه حل سریع تری برای lifecycle-aware کردن کلاس ها با نام Android architecture components ارائه داده که کمک بزرگی به معماری های اندروید است. ما دو کلاس مهم و ساده ارائه شده توسط گوگل را در زیر آورده ایم که البته استفاده زیادی دارند:

            • ViewModel

            یکی از کارهایی که ViewModel برای آن ساخته شده این است که از داده های مرتبط به UI زمان چرخش صفحه در برابر destroy شدن محافظت می کند.

            • LiveData

            با استفاد از LiveData می توان شی های داده ای ساخت که زمان تغییر داده در لایه های زیرین مرتبط به دیتابیس، به UI اطلاع داد تا همگام با دیتابیس به روز شود.

            مثال 4:

            بیایید نگاهی به نحوه پیاده سازی مثال قبل در معماری MVVM بیندازیم.

            class MainViewModel(private val service: WorldService) : ViewModel() {
            	
            
            	    val textValue = MutableLiveData<String>()
            	    val inProgress = MutableLiveData<Int>()
            	
            
            	    private var disposable: Disposable? = null
            	
            
            	    fun onButtonClicked() {
            	        inProgress.value = View.VISIBLE
            	        disposable = service.requestHello()
            	                .subscribeOn(Schedulers.io())
            	                .observeOn(AndroidSchedulers.mainThread())
            	                .subscribe(this::onServiceResponse)
            	    }
            	
            
            	    override fun onCleared() {
            	        disposable?.dispose()
            	    }
            	
            
            	    private fun onServiceResponse(response: String) {
            	        inProgress.value = View.GONE
            	        textValue.value = response
            	    }
            	}
            	
            
            	class MainActivity : AppCompatActivity() {
            	
            
            	    @Inject lateinit var viewModelFactory: MainViewModelFactory
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	        Dependencies.inject(this)
            	
            
            	        val viewModel = getViewModel().apply {
            	            textValue.observe(this@MainActivity, Observer { helloTextView.text = it })
            	            inProgress.observe(this@MainActivity, Observer { it?.let { progressBar.visibility = it } })
            	        }
            	        button.setOnClickListener { viewModel.onButtonClicked() }
            	    }
            	
            
            	    private fun getViewModel() = ViewModelProviders.of(this, viewModelFactory).get(MainViewModel::class.java)
            	}
            
            

            همانگونه که مشاهده می کنید ما مجددا از Dagger استفاده کردیم اما نکته قابل توجه در معماری MVVM اینجاست که ما کلاس ViewModel را از ViewModelProvider گرفتیم پس نگرانی از بابت حفظ داده در تغییرات حالت نخواهد بود. به علاوه به کامپوننت های lifecycle-awareness دیگری هم نیازی نخواهد بود چرا که ViewModel دیگر ارتباطی با View ندارد.

            حال Activity به LiveData برای مشاهده تغییرات در UI دقت دارد و همچنین unsubscribing هم درون خود کامپوننت های کتابخانه مدیریت می شود و دیگر نیازی به نوشتن کد های boilerplate نخواهد بود.

            دقت داشته باشید که دستورات اتصال به بک اند یا همان فراخوانی api ها همگی درون ViewModel انجام می شوند کاملا مستقل از چرخه حیات View. البته همان دستورات request هم در بک گراند و به صورت asynchronous انجام می شوند.

            خب به طبع با این حالات ما نگرانی های کمتری نسبت به مواردی چون lifecycle-awareness خواهیم داشت. همین امر باعث دقت به موارد دیگر و همچنین سرعت کار خواهد شد.

            این خوب نیست!

            بخشی از کد مثال قبل در هر دو معماری MVP و MVVM که به صورت asynchronous پیاده شده بودند که تا میزان زیادی به هم شبیه هستند و هر دو عملکرد قابل قبولی دارند. اما بیاید این دو معماری را زمانی که در حالت synchronous هستند مقایسه کنیم. زمانی که controller دستورات را مستقیما به view ارسال میکند.

            مثال 5: پیاده سازی معماری MVP به صورت synchronous

            class MainPresenter(private val view: MainView) {
            	
            
            	    fun onHelpButtonClicked() {
            	        view.showHelp()
            	    }
            	
            
            	    interface MainView {
            	        fun showHelp()
            	    }
            	}
            	
            
            	class MainActivity : AppCompatActivity(), MainPresenter.MainView {
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	
            
            	        val presenter = MainPresenter(this)
            	        helpButton.setOnClickListener { presenter.onHelpButtonClicked() }
            	    }
            	
            
            	    override fun showHelp() {
            	        HelpDialog().show(supportFragmentManager, null)
            	    }
            	}
            
            

            همانگونه که مشاهده می کنید Presenter مانند سابق view را مستقیما فراخوانی می کند.(اما این بار ممکن است دردسر ساز شود چرا که این اتفاقات synchronous رخ می دهد.)

            مثال 6: پیاده سازی معماری MVVM به صورت synchronous

            در معماری MVVM نسبت به معماری MVP اوضاع کمی متفاوت است.

            class MainViewModel : ViewModel() {
            	
            
            	    val showHelpEvent = SingleLiveEvent<Void>()
            	
            
            	    fun onHelpButtonClicked() {
            	        showHelpEvent.call()
            	    }
            	}
            	
            
            	class MainActivity : AppCompatActivity() {
            	
            
            	    override fun onCreate(savedInstanceState: Bundle?) {
            	        super.onCreate(savedInstanceState)
            	        setContentView(R.layout.activity_main)
            	
            
            	        val viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
            	        subscribeToNavigationChanges(viewModel)
            	        helpButton.setOnClickListener { viewModel.onHelpButtonClicked() }
            	    }
            	
            
            	    private fun subscribeToNavigationChanges(viewModel: MainViewModel) {
            	        // The activity observes the navigation events in the ViewModel
            	        viewModel.showHelpEvent.observe(this, Observer {
            	            HelpDialog().show(supportFragmentManager, null)
            	        })
            	    }
            	}
            
            

            همانگونه که در معماری MVVM مشخص است ما از ViewModel استفاده می کنیم و در حالت synchronous هم ViewModel خطرات MVP را برای ما از بین برد.

            ViewModel دستورات را درون LiveData قرار می دهد و از طریق آن، و نتیجه را به View پاس می دهد که این نتیجه هم به صورت observe کردن جریان showHelpEvent انجام می گیرد.

            نکته:
            SingleLiveEvent کلاسی است که زمان اجرا اطمینان حاصل می کند که رویداد تنها یکبار آماده خوانده شدن است و از نمایش چندباره نتیجه جلوگیری می کند.

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

            تبدیل معماریMVP به MVVM در اندروید

            اخیرا MVVM محبوبیت بسیاری بین توسعه دهندگان اندروید پیدا کرده است. در این مقاله نیز ما سعی کردیم مثال های کاربردی و ساده ای را پیاده کنیم تا نحوه تبدیل Presenter به ViewModel را ببینید و همچنین به چرایی مهاجرت به MVVM پی ببرید.

            خلاصه مقایسه معماری MVP و MVVM

            در این پست از تجاری اپ ما با مثال های ساده تفاوت دو معماری MVP و MVVM را مشخص کردیم. چیزی که در انتها می توان نتیجه گیری کرد این است که MVVM استقلال بیشتری در کدها ایجاد می کند و در نهایت نگرانی از بابت ایجاد وابستگی بین کدها نداریم. کدهای boilerplate کمتری ایجاد می شود. ما را تشویق به کد نویسی واکنش گرا می کند. به علاوه خود گوگل هم کتابخانه هایی برای توسعه راحت تر کدها با معماری MVVM پیشنهاد داده است که خیال توسعه دهندگان را از لحاظ مدیریت lifecycle کلاس ها راحت می کند. همین امر باعث crash و memory leak کمتری نیز می شود.

            برای سناریو هایی که controller نیاز دارد به صورت synchronously با UI در ارتباط باشد و تغییرات اعمال کند، presenter بهتر عمل کرد. شاید به همین دلیل است که گوگل پیشنهاد می کند هر دو ViewModel و Presenter را در پروژه های پیچیده که UI با جزییات زیادی دارند، استفاده کنید. مخصوصا زمانی که شما میخواهید جزییات UI را test کنید مانند انیمیشن ها و…

            در نهایت باید این را هم بگوییم که اگر از معماری MVP استفاده می کنید و در پروژه شما به خوبی عمل می کند واقعا نیازی نیست که به MVVM مهاجرت کنید. اما اگر هم می خواهید مهاجرت کنید می توانید صفحه به صفحه این کار را انجام دهید.

            اگر از MVVM استفاده می کنید باید در نظر داشته باشید که از کتابخانه Data Binding هم استفاده کنید. که مکمل ویژه ای برای ViewModel به حساب می آید و کدها را کم و بهینه می کند.

            امیدوارم این آموزش برای شما مفید بوده باشد…

            کلمات کلیدی: مقایسه MVP و MVVM,مقایسه دو معماری MVP و MVVM,یزاین پترن MVP,یزاین پترن MVVM,الگوی طراحی MVP,الگوی طراحی MVVM

            اشتراک گذاری

            پست های مرتبط

            دستورات جریان کنترل (Control flow statements) یا دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت Dart

            دستورات جریان کنترل (Control flow statements) یا دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت Dart

            30 بهمن 1400

            دستورات شرطی و حلقه ها در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب
            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت یا Dart

            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت یا Dart

            30 بهمن 1400

            آموزش عملگرها یا Operator ها در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب
            توابع در زبان برنامه نویسی دارت (Dart)

            توابع در زبان برنامه نویسی دارت (Dart)

            27 بهمن 1400

            توابع در زبان برنامه نویسی دارت (Dart)


            ادامه مطلب

            دیدگاهتان را بنویسید لغو پاسخ

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

            ساخت اپلیکیشن های موبایل

            • ساخت اپلیکیشن فروشگاهی
            • ساخت اپلیکشن ابزاری و خدماتی
            • ساخت اپلیکیشن آموزشی
            • و هزاران موضوع دیگر

             
            کلیک کنید

            آخرین دیدگاه ها

            • 9 اسفند 1401

              مهری اصغری نظر در پیاده سازی اولین پروژه با فلاتر Flutter

            • 26 آبان 1401

              سجاد نظر در پروژه مدیریت سیستم مدرسه با سی شارپ و sql server

            • 7 خرداد 1401

              داودی نظر در آموزش استفاده از ckeditor همراه با آپلود عکس در لاراول 6

            تجاری اپ در شبکه های اجتماعی

            لوگوی تایید پرداخت آنلاین

            2015-2022 © تمامي حقوق مادي و معنوي اين وب سايت نزد تجاری اپ محفوظ بوده و هر گونه کپي برداري از مطالب پيگرد قانوني به همراه دارد! | طراح سایت : ProgRun
            سفارش پروژه
                      هیچ نتیجه ای یافت نشدمشاهده همه نتایج