Pull to refresh

Comments 4

DISCLAIMER: Я буду говорить относительно Vue и только в рамках Vue. Если вы собираетесь читать относительно концепции в других фреймворках и языках, то можете скипать, так как обсуждение каждого фреймворка или другого подхода требует другой аргументации и обсуждения в целом. Данный комментарий больше ориентирован на тех кто воодушивившись уже собрался тащить такой подход к себе в проект

А ради чего Vue который из коробки изначально был MVVM (в последствии реактивная модель по своей сути вышла за рамки классического MV*) пытаться превращать в MVC? Концепции заложенные во фреймворк уже прекрасно работают относительно разделения, а классические подходы в разработке фронтенда закрепляют это еще лучше.

Ну и перепишем предложенный код как он мог быть написанным в классическом Vue исполнении:

"Модель":

function useProgress() {
  const isGoing = ref(false)
  const percentages = ref(0)

  function start() {
    isGoing.value = false
    percentages.value = 0
  }

  function finish() {
    isGoing.value = false
    percentages.value = 0
  }

  // сохраню изначальную задумку автора
  function update(percentages: number) {
        switch (true) {
        case percentages <= 0:
            percentages.value = 0;
            break;
        case percentages >= 100:
            percentages.value = 100;
            break;
        default:
            percentages.value = percentages;
		}
  }

  return {
    // для понятности использую самый наивный метод реализации readonly. 
    // однако так писать не рекомендую
    isGoing: computed(() => isGoing.value),
    percentages: computed(() => percentages.value),
    start,
    finish,
    update
  }
}

Да, это просто композабл. Композаблы это прекрасные кирпичики чтобы выносить бизнес логику или позволять различным компонентам использовать одну функциональность. Создавать классы нет никакой нужды и я надеюсь, что автор это сделал исключительно только ради того, чтобы быть не столь сильно привязанным ко Vue подходам

Представление:

Да не нужно никакую model создавать для передачи. Классические подходы работают прекрасно: пропсы+события это и есть МОДЕЛЬ с которой работает данный компонент (если уж мы начали так представлять). Соответственно

<ProgressBar :is-going :percentages />

Если вам так нравится концепция: передать "все", то есть уже для этого механизм

<ProgressBar v-data="progress" />

Контроллер:

Почему компонент-родитель является контроллером опустим за скобкой, но в классическом представлении для такого уже есть паттерн smart dumb components, когда простое представление контролирует умный компонент.

Итого: натянув MVC предложенный в статье на Vue приложение вы ломаете привычный флоу для Vue разработчиков, усложняете разработку пытаясь реализовать и поддерживать инородные сущности и увеличиваете количество необходимого кода для их поддержания. При этом классические паттерны для работы со Vue (да и в целом Frontend-ом) уже давно выведены и перед такими трюками лучше вначале изучить их и сравнить с тем что могут дать вам они.

Вообще, MVP - это больше про разделение на части большущего кода, который прячется за api компонента. Поэтому сравнивать MVVM с MVP на примере прогресс бара пахнет сомнительной затеей. И фреймворк тут не важен.

Я думаю, что ваш комментарий поможет применить идеи из статьи при работе с Vue и случайно не разругаться с остальными разработчиками на проекте. Мой подход к написанию кода действительно отличается от принятых практик, потому что я привязываюсь к концепциям, а не к принятым в фреймворке реализациям. Что позволяет мне переключаться между фреймворками не замечая разницы. Это не всем подходит, так что спасибо за дополнение :)

Объясню некоторые выборы в статье, возможно вы взгляните на них под другим углом.

На счёт composable. Вы создали функцию, которая возвращает объект, в котором есть поля и процедуры, работающие с этими полями. То есть - вы создали класс (шаблон для создания объектов). Тут уже дело договорённостей. Если на проекте всю кастомную логику держат в composable, во Vue так принято и разработчикам так привычнее - конечно делайте через них. Суть от этого не изменится - это всё еще класс. Я же люблю для создания объектов использовать механизм, который для них предназначается. А функциям и процедурам отводить свою отдельную роль.

На счёт представления не очень понял. Внутри компонента ProgressBar.vue всё равно придётся указать тип данных пропса (в моём случае Progress). И он должен быть без методов (ProgressModel не подходит), потому что это, как вы правильно сказали, dumb component. И на что он будет ссылаться, если нет разделения на данные и модель, мне не понятно. Но у вас компонент ProgressBar контролируется через модель - а это главное. Остальное - детали реализации, так что для меня это не принципиально.

На счёт контроллеров. В статье я дал им определение: "Это класс объектов, которые подписываются на события от устройств ввода". В моей реализации компонент-родитель подписывается на события, так что относительно MVC для Progress - он контроллер. Да, он же является и mediator (в ваших терминах "smart component"). Но контроллером, относительно MVC для progress, он от этого быть не перестаёт.

Ещё раз спасибо за проявленный к статье интерес и полезное прикладное дополнение для разработчиков на Vue

Статья понравилась. Лёгкое и интересное повествование о важной теме, учитывая как слабо развиты концепции MVC, MVP, MVVM в современном вебе. Однозначно жду развития идей и анализа. Спасибо!

Sign up to leave a comment.

Articles