Massive View Controller - IOS - Решения

16

Я уверен, что у каждого нового разработчика iOS есть следующая проблема: контроллеры представления очень быстро заполняются кодом для различных целей, легко получая до 500+ строк кода.

Вот как это выглядит для двух основных и общих экранов:

1) Экран формы: введите описание изображения здесь

2) Экран контроллера табличного представления введите описание изображения здесь

До сих пор я читал о двух разных решениях:

  1. Первое решение: https://bendyworks.com/single-responsibility-principle-ios/ . Это основано на Уведомлениях, оно полностью отделяет Контроллер Представления от (Представления) Модели Представления и таким образом уменьшает код в Контроллере Представления. Я думаю, что у этого есть обратная сторона взлома кода, подобного структурам Go-To. Это выглядит так: введите описание изображения здесь

  2. Второе решение сохраняет те же самые переполненные контроллеры вида (действия кнопок выполняются внутри VC и т. Д.). но использует такие библиотеки, как TPKeyboardAvoiding , BlocksKit или другие решения, большинство из которых основано на категориях. С этим вторым решением код значительно сокращен, но контроллер представления все еще несет большую ответственность.

Что вы думаете об этих решениях? Что лучше? Есть ли лучший?

Ravul
источник
5
Я не могу дать хороший ответ из-за времени, но это должно указать вам правильное направление.
Майк Д
Я намерен собрать как можно больше хороших ответов, чтобы, наконец, преодолеть эту проблему, что так много новых разработчиков. Спасибо за ссылку, если я найду что-то новое, я обязательно опубликую это здесь.
Равул
Вот отличный разговор о борьбе с толстыми контроллерами представления Энди Матущаком https://realm.io/news/andy-matuschak-refactor-mega-controller/
Томаш Бёк

Ответы:

6

Мы можем использовать MVVM для решения этой проблемы.

Модель Model-View-ViewModel, или шаблон MVVM, как его обычно называют, является шаблоном дизайна пользовательского интерфейса. VM берет всю логику о подготовке данных модели для пользовательского интерфейса из VC.

Пример: у
вас есть объект модели с некоторыми полями, вы хотите отформатировать некоторые из них, произвести расчеты и объединить их.

В случае MVC вся эта логика находится во ViewController.
В MVVM вы перемещаете все это из VC в VM.

ВМ подготовит все данные для пользовательского интерфейса, а VC просто установит их следующим образом.

(в классе VC)

self.descriptionLabel = self.viewModel.textForDescriptionLabel;

Учебники и темы:

kaspartus
источник
3
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки.
Барт ван Инген Шенау
Я согласен с Бартом. Если никто не опубликует резюме всех этих методов, я сделаю один, как только пойму и протестирую их все.
Равул
2
@Ravul обновленный ответ
kaspartus
Я проголосовал за ваш ответ и благодарю вас за эту идею. Я просто читаю о функционально-реактивном программировании, и это кажется хорошей идеей. Я думаю, что ответом на этот вопрос является перечисление с несколькими преимуществами, недостатками и, по крайней мере, одной концептуальной диаграммой для следующих 4 способов решения проблемы: 1) Реактивное какао 2) КВО 3) Метод делегирования и 4) Классический способ написание View Controller. Я напишу это, как только протестирую все эти методы, если никто до меня этого не сделал. Если тем временем я найду новые пути, это даже лучше.
Равул
3

Раньше мне приходилось распутывать код в контроллерах вида большого размера, и это поначалу мешало мне ориентироваться в контенте. Одна важная вещь, которую я осознал, заключается в том, что один только размер View Controller не был достаточной причиной, чтобы разбить вещи на части. Есть сложность иметь один большой файл, а также сложность иметь кучу маленьких файлов. Вот несколько веских причин для рефакторинга, чтобы разбить View Controller на более мелкие части:

MVC

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

Несколько элементов управления с View Controller в качестве источника данных

Если на экране имеется несколько элементов управления, в которых в качестве источника данных используется View Controller, рассмотрите возможность их разбиения на отдельные объекты источника данных и используйте их в качестве источника данных. Или вы также можете разбить их на отдельные контроллеры представления (например, если у вашего View Controller есть табличное представление в дополнение к другому контроллеру, вы можете разбить его на собственный класс Table View Controller).

Дубликат кода

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

Вот несколько дополнительных советов, чтобы минимизировать сложность View Controller:

Раскадровка вместо Programmatic

Создание элементов View - это много кода, а код геометрии фрейма - это тоже много работы. Если это еще не сделано, рассмотрите возможность использования автоматических ограничений макета и размещения как можно большего количества элементов представления в раскадровке.

Ненужный код / ​​комментарии

Также обязательно удалите ненужный код / ​​комментарии. Часто новый файл View Controller будет содержать методы, которые вы не используете. Если вы не используете такой метод, didReceiveMemoryWarningто его можно безопасно удалить. Кроме того, из-за того, что файл View Controller очень большой, иногда бывает страшно удалить старый код или комментарии. Не откладывайте это! Это только добавляет сложности.

Уведомления

Чтобы ответить на ваш вопрос об уведомлениях: Уведомления - это не золотой молоток, который можно использовать со всем. Я считаю уведомления полезными, когда необходимо обновить несколько контроллеров представления одновременно из-за одного конкретного действия. Будьте осторожны с уведомлениями, однако, чрезмерное их использование может причинить вам много боли, пытаясь отследить их.

Корей Хинтон
источник
2

Есть одна особая архитектура, которую они называют VIPER (View, Interactor, Presenter, Entity и Routing). Я постараюсь возобновить здесь то, что вам нужно знать:

Посмотреть

  • это фиктивные взгляды;
  • содержать объекты, такие как UIView, UIViewController, UILabel и т.д .;
  • ожидает контент от докладчика ;
  • обрабатывать взаимодействие с пользователем и передавать его на уровень Presenter .

Ведущий

  • не знает объектов пользовательского интерфейса;
  • получить входные данные из слоя View ;
  • обрабатывать логику представления (метод add представит другой экран);

Маршрутизация

  • обрабатывать навигационную логику и анимацию перехода;
  • знает такие объекты, как UINavigationController, UIWindow и т. д .;

Итак, что я думаю, вы очистите в своем коде:

  • валидация данных переместится на уровень Presenter ;

  • навигация переместится на объекты каркаса ( слой маршрутизации );

  • разделите ваш контроллер вида, соблюдая принцип СУХОГО ;

  • Сложные экраны будут иметь два или более видов и докладчиков.

Вы должны увидеть следующую ссылку об архитектуре VIPER http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/

Удачи!

orafaelreis
источник
1
Эта архитектура работает для небольших приложений? Похоже, вам нужно создать много объектов, чтобы представить его в проекте.
Томаш Бек
да, я согласен, что это больше объект, чем традиционный MVC, но это того стоит. Вы можете увидеть один простой пример, который я создал в этом году. Github.com/orafaelreis/cascavel Cascavel - это базовый проект для инициализации проектов VIPER.
orafaelreis
Отлично ! Архитектура VIPER, кажется, разработана именно для того, чтобы избежать проблем с массивными контроллерами представления.
Кристоф