На бумаге всё выглядит очень просто и понятно, однако на деле приходится сталкиваться с трудностями.
Первая и основная проблема это установление зависимостей между частями модуля (между Presenter, Interactor и т. п.). Подходов к решению этой проблемы существует два:
1) прописывание всех зависимостей вручную
2) использование библиотек для инъекции зависимостей (например, Typhoon).
Первый вариант является наиболее сложным и затратным по времени. Нужно всё верно связать и сделать так, чтобы не было утечек памяти. Из-за чего появляются утечки? Из-за двойных связей — Router имеет ссылку на Presenter, а Presenter, в свою очередь, на Router. Точно так же обстоит дело с View и Presenter. Для того чтобы избежать этой проблемы, нужно в одной из связей использовать weak-ссылку на объект (Presenter на View, Presenter на Router). Это позволит уйти от циклической зависимости и уничтожить объект, когда он будет больше не нужен. Главный плюс данного метода — всё прозрачно: вы полностью контролируете время жизни объектов.
Использование сторонних библиотек должно упростить жизнь разработчику и позволить ему не переживать за зависимости. Однако появляется другая проблема — сторонние библиотеки имеют свойство меняться или вообще исчезать. Учитывая, что данная библиотека будет отвечать за связность проекта, ее потеря будет катастрофической, придется либо искать другую библиотеку, либо делать всё вручную. При изменении библиотеки возможно придется что-то переписывать в коде. В любом случае, это займет немало времени.
Другая беда, приходящая при использовании VIPER, заключается в том, что многие сторонние библиотеки и некоторые стандартные средства языка (UITableView) не пригодны для этой модели. Чаще всего нарушается принцип единой ответственности. С одним из таких нарушений нам пришлось столкнуться на нашем проекте: до перевода на VIPER мы использовали библиотечный textField, в котором был метод, проверяющий, является ли содержимое email адресом. Вызывался он обращением к экземпляру этого класса. Получалось, что логика находилась внутри раздела View. Решений было несколько:
— пренебречь принципом единой ответственности и оставить всё как есть;
— передать этот textField в Interactor, но это непростой объект, следовательно, снова нарушение VIPER;
— избавиться от этой библиотеки и написать проверку самому внутри Interactor.
В данной ситуации это маленькая проблема, которая решилась довольно быстро (мы пошли последним путем, написав всё сами), однако бывают ситуации куда более серьезные, требующие бо́льших умственных и временных затрат.