Pull to refresh

Comments 18

VIPER предлагает отделить всю логику во множество мелких классов с разделенными обязанностями. Это должно бы облегчить тестирование, но так не всегда. Да, написать юнит-тест для простого класса легко, но большинство из таких тестов ничего не тестируют.

Кто запрещает написать интеграционные тесты в дополнение к юнит тестам?

И продолжение:


Правильный подход к тестированию должен бы включать в себя тестирование интерактора и презентера сразу, ведь эти две части сильно связаны друг с другом. Кроме того, поскольку мы разделяем логику на два класса, нам нужно намного больше тестов по сравнению с одним классом. Это простая комбинаторика: у класса A есть 4 возможных состояния, а у класса B — 6, соответственно их комбинация имеет 24 возможных состояния, и вам нужно их протестировать.
Думаешь, что если написать все в одном классе, то у него будет меньше состояний и при этом код будет чище, менее связян и легок в поддержке? И при этом его еще будет легко протестировать?

Смысл тестирования сущностей отдельно друг от друга в том, что в тесте все сущности кроме тестируемой являются идеальной моделью себя самих. Тестируется то, как презентер взаимодействует с идеальным интерактором и наоборот.
Будет ли у этого приложения длительный жизненный цикл?

Довольно частая ситуация, когда планируется сдать проект и забыть. А потом через пол года заказчик возвращается с новыми фичами.


Достаточно ли стабильны требования? В противном случае вы столкнетесь с бесконечным рефакторингом даже при внесении мелких изменений.

Тут какраз хорошая модульная архитектура очень поможет.


Вы действительно тестируете свои приложения? Будьте честны с собой.

Тестировать надо, то что надо тестировать. Пробросы вызовов тестировать можно только для галочки покрытия тестами. Но в любом, даже очень простом приложении есть немного бизнес логики — вот именно ее и надо проверить и зафиксировать тестами.


Такое впечатление, что автор статьи забыл зачем нужна архитектура.

Ваша правда. :) Но мне кажется, что и в статье есть доля истины.


Все больше склоняюсь к тому, что MVP — та самая золотая середина, по понятности и разделению ответственности. :)

MVP — это не архитектура приложения
MVP — это способ организации презентационного слоя
MVP — это архитектурный паттерн. Архитектура — это взаимозвязь данных и логики (то есть формат данных, их связь с логикой и прочие вещи). Можно и с MVP паттерном как и с любым другим паттерном сделать плохую архитектуру.
MVP — это паттерн для организации презентационного слоя, но никак не для построения архитектуры всего приложения. Вы с этим собираетесь спорить?

Да, собираюсь. :) MVP — это тот же VIPER, в котором интерактор включен в презентер, а роутер присутствует в неявном виде. :)

то есть у вас вся архитектура приложения ограничивается презентационным слоем?

Почему в аббревиатуре "MVP" вы упорно видите только букву "P"? :)

А почему вы ставите знак равенства между презентером (который скрывается под буквой P) и презентационным слоем? В данном случае к презентационному слою относится и буква V.
Смысл моего послания состоит в том, что MVP — это не архитектура приложения, а только способ построения слоя, отвечающего за представление данных. При грамотно построенной архитектуре, с разделением ответственности между различными слоями приложения, возможно безболезненная замена MVP на MVVM или на что-то другое.
и хотя под буквой M у нас и скрывается Model, но MVP — не про то, как организовать Model, а про то, как организовать презентационный слой
У каждого программиста обычно свое понимание MVP. В вашем понимании MVP, кто общается со слоем данных? Presenter напрямую? А если нужно исходные данные немного преобразовать перед отображением? А кто отвечает за обработку переходов между экранами?

Извините, я не очень знаком с типичной архитектурой iOS-приложений. Поэтому часть вопросов может показаться глупой :)
кто общается со слоем данных? Presenter напрямую?

Да, презентер напрямую.


А если нужно исходные данные немного преобразовать перед отображением?

Их тоже готовит презентер.


А кто отвечает за обработку переходов между экранами?

Презентер решает на какой экран нужно перейти, а сам переход делегирует выполнять своему вью.

А нет ли здесь нарушения SRP? Presenter получается таким god-object, который знает почти все о работе приложения. Получается, что тут целых три причины для изменения презентера:


  1. Изменение способа отображения данных
  2. Изменение слоя данных
  3. Изменение логики переходов по экранам внутри приложения

Достаточно хрупкая и размытая абстракция, не находите?


Почему бы не инкапсулировать 2-й пункт в Interactor, 3-й — в Router? Получится, конечно же, больше классов. Но они маленькие, имеют строгую зону ответственности и проще тестируются.

Статья очень сильно воспринимает VIPER только со стороны написания short-term проектов. Т.е. когда вы написали проект, сделали 1-2 итерации и забыли.
На деле же, VIPER активно пиарили и пиарят люди, которые сидят на long-term проектах, где такой подход экономит кучу временных затрат на тестирование и рефакторинг.
Понятное дело, что зачастую применение VIPER в приложении, где нужно 20 экранов с логикой запрос на сервер-показ данных в таблице, карте и т д, абсолютно не оправдывает себя.
Но, когда ты работаешь в проекте где 120+ экранов с 12(только iOS) разработчиками в команде и где Unit, Integration, UI тестирование стоит как требование наравне с написанием кода — то VIPER это возможность избегать множества конфликтов и костылей.
Позвольте перефразировать: «Нас 12(только iOS) разработчиков в команде, на проекте с 120+ экранов, мы избежали множество конфликтов, но так и не разобрались куда девать UIAlertController ...»
Sign up to leave a comment.

Articles