Подтвердить что ты не робот

Где операции с моделями принадлежат шаблонам проектирования приложений?

Скажем, мы хотим сделать application, содержащий следующее:

  • Асинхронный и потребляющий время operations на выбранном objects
  • Для определенного object мы хотим получить доступ к status связанного operation.
  • Возможность show, cancel и pause выполнять эти операции из multiple views.

Тогда мой вопрос следующий:

Где эти operations и их progress/status принадлежат шаблону проектирования приложений?

Чтобы включить его в контекст, это фиктивное приложение:

Пример приложения:

У нас есть приложение, в котором вы можете применить разные Filters к Images. Приложение состоит из Directory View и Detail View.

  • Каждый filter может быть применен asynchronously к любому image из каждого view.
  • filter -операция может быть observed и canceled из views.
  • Операция с фильтром не может быть запущена, если для тех filter-type и image уже есть один, или если такой filter уже создал result.
  • В этом фиктивном приложении представления следуют, но в общем случае вы не сможете передавать информацию непосредственно между представлениями.

Просмотр каталога

введите описание изображения здесь

Прогресс

Развязка Service Layer или Network Controller с view и Model в шаблоне проектирования, например MVC или MVVM, достаточно проста, если вы не предоставляете больше UX feedback чем a spinner, когда есть активный network request.

Но когда я работаю над приложением, подтверждающим вышеприведенные критерии, я всегда заканчиваю либо

  • Не позволяя user изменять view во время operation
  • Tagging операции с id объекта, обработанного в данный момент и передающего его в views, или поиск в Network Controller непосредственно из views/view controllers
  • Создаем отдельный entities для operations, и вдруг у меня есть request operation в моем Model

Таким образом, очевидно, что есть (очень вонючие) способы обойти это, но все они чувствуют себя грязными и не связаны с тем, как шаблоны предназначены.

Таким образом, с точки зрения архитектуры и дизайна, как бы вы приблизились к этому?

4b9b3361

Ответ 1

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

Этот объект обещания может быть передан из вида для просмотра или может быть подан с сетевого уровня по нескольким запросам (просмотр A запускает операцию, просмотр B пытается позже отпустить его, но он уже работает, поэтому он получает то же обещание объект).

Это означает, что уровень сервиса или сетевой уровень в этом случае должен представлять, какие операции, запросы, текущие для какого-либо объекта, не так ли? Потому что вы не хотите пинать запрос только для получения объекта обещания, если кнопка должна быть скрыта, если операция уже запущена. Я предполагаю, что вы сохранили бы эти объекты обещания вне вашей модели приложения, так как они не живут между сеансами, а сетевой уровень сохранит их по URL-адресу, но как бы вы обычно обслуживали это обратно с сетевого уровня, не подвергая себя много сетевого уровня к ui?

На сетевом уровне есть удобные методы для использования пользовательского интерфейса для запуска запросов, инициируемых пользователем. Сетевой уровень определяет, был ли запрос уже запущен и возвращает то же обещание. Даже если сетевой уровень начал процесс внутри (автообновление и т.д.), Он все равно может вернуть обещание обратно в пользовательский интерфейс, если пользовательский интерфейс попытается запустить тот же процесс.

Объекты обещания живут только до тех пор, пока операция продолжается. Фактически у меня есть операция, которая является истинным держателем объекта обещания, а сетевой контроллер имеет очередь операций. Затем, когда приходит запрос, я ищу очередь для существования этой операции и, если она существует, возвращает обещание от операции. Если он не существует, я создаю новую операцию, помещаю ее в очередь и возвращаю ее объект обещания.

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

Теперь, если это обновление данных, обещание не требуется для обновлений данных, NSFetchedResultsController будет обрабатывать это. Обещание в этой ситуации обрабатывает запросы только "я активен" и "отменю меня".

Ответ 2

Там будет много способов сделать это. Но вот идея... Возможно, вы можете использовать messaging как стиль: определить канал состояния, возможно, использовать модель pub-sub для получения статуса/выполнения текущих операций. Таким образом, процесс выполнения операций публикует статус на канале, а ваши множественные просмотры подписываются на этот канал и отображают статус. Теперь, если вам нужно отменить/приостановить операции, возможно, вам понадобится другой канал управления. Вам нужно управлять concurrency, заказом и т.д.