путаница для ответственности view и viewmodel в архитектуре mvvm - PullRequest
0 голосов
/ 15 февраля 2020

я спрашивал это несколько дней: go здесь , но не получил никакого ответа

У меня путаница в отношении того, какой код должен быть отображен, а что в viewmodel

например, события клика

приведен фрагмент кода примера приложения Google ToDo для демонстрации архитектуры приложения ( Ссылка ):

//this code is placed in view (TasksFragment)
override fun onOptionsItemSelected(item: MenuItem) =
        when (item.itemId) {
            R.id.menu_clear -> {
                viewModel.clearCompletedTasks()
                true
            }
            R.id.menu_filter -> {
                showFilteringPopUpMenu()
                true
            }
            R.id.menu_refresh -> {
                viewModel.loadTasks(true)
                true
            }
            else -> false
        }

private fun showFilteringPopUpMenu() {
    val view = activity?.findViewById<View>(R.id.menu_filter) ?: return
    PopupMenu(requireContext(), view).run {
        menuInflater.inflate(R.menu.filter_tasks, menu)

    setOnMenuItemClickListener {
        viewModel.setFiltering(
            when (it.itemId) {
                R.id.active -> TasksFilterType.ACTIVE_TASKS
                R.id.completed -> TasksFilterType.COMPLETED_TASKS
                else -> TasksFilterType.ALL_TASKS
            }
        )
        viewModel.loadTasks(false)
        true
    }
    show()
  }
}

, как вы можете см. есть 3 три пункта для меню

2 из них делегированы для viewmodel и один обрабатывается в представлении

, кроме того, есть некоторые логики c в представлении, которые принимают решение на основе идентификатора представления , но в определении mvvm сказано, что не должно быть никаких условий в виду

1 Ответ

1 голос
/ 15 февраля 2020

Это действительно легко. Зависит от того, что каждый архитектурный вопрос написан не золотыми буквами. Но есть некоторые лучшие практики, которым нужно следовать. Вы хотите, чтобы ваши занятия были короткими, удобочитаемыми и наиболее важными для тестирования. Перемещение вашей бизнес-логики c в модель представления действительно важно, потому что тогда вы можете протестировать вашу viewModel с помощью тестов Junit без указания насмешливых компонентов c Android.

Упомянутый вами when находится в В некотором роде бизнес-логика c, но it.itemId, который вы видите, действительно зависит от представления и находится в области действия команды run, переход в viewmodel в качестве параметра функции setFiltering был бы заслуживающим внимания для немногих разработчиков

Даже расширенные модели чистой архитектуры могут иметь и они фактически имеют статус, который отображается, когда, например,

 private fun handleDataState(resource: Resource<List<ProjectView>>) {
        when (resource.status) {
            ResourceState.SUCCESS -> {
                progress.visibility = View.GONE
                recycler_projects.visibility = View.VISIBLE
                resource.data?.let {
                    adapter.projects = it.map { mapper.mapToView(it) }
                    adapter.notifyDataSetChanged()
                }
            }
            ResourceState.LOADING -> {
                progress.visibility = View.VISIBLE
                recycler_projects.visibility = View.GONE
            }
        }
    }

РЕДАКТИРОВАТЬ

первая функция viewModel.clearCompletedTasks() делегирован модели представления, потому что вы собираетесь очистить кеш в (обычно) слое хранилище , другими словами, вы вызываете то, что называется прецедентом, делегируя так называемые бизнес-логики c вне представления, популярного сегодня, чтобы сделать его «настолько глупым, насколько это возможно», вы не хотите, чтобы представление очищало задачи, но хотите что нижележащий объект, представляющий задачи, очищается и только тогда отображается в виде статуса.

То же самое относится и к третьему viewModel.loadTasks(false), это также сценарий использования и, кроме того, вы также передаете логическое значение, которое будет введено в viewModel, или даже дальше, если вы используете чистую архитектуру. Основное правило: представление должно иметь компоненты представления, бизнес-логика c должна оставаться в модели представления. Это хорошая отправная точка, но имейте в виду, что MVVM может применяться к другим типам более сложных архитектур.

...