Почему Apple документирует, что получение ManagedObjectContext из UIApplicationDelegate плохо? - PullRequest
5 голосов
/ 31 июля 2011

Просто любопытно, почему ManagedObjectContexts следует передавать UIViewControllers при их создании, а не просто извлекать их из UIApplicationDelegate?

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

Спасибо!

Ответы [ 4 ]

7 голосов
/ 31 июля 2011

Представьте, что я прошу вас выполнить какое-то задание, например, покрасить комнату.Если я просто скажу вам: «Иди, нарисуй комнату», тебе нужно будет задать мне много вопросов, например:

  • Какая комната?
  • Где краска?
  • Где щетки?
  • Стоит ли использовать тряпку?

Короче говоря, вы не сможете выполнить задачу без моей помощи.Если вам придется каждый раз зависеть от меня, вы не будете очень гибким художником.Один из способов справиться с этой проблемой - дать мне все необходимое в самом начале.Вместо того, чтобы «покрасить комнату», я скажу «пожалуйста, покрасьте комнату № 348, используя это ведро с краской и эту кисть, и не заморачивайтесь с помощью тряпки».Теперь у вас есть все, что вам нужно, и вы можете получить право на работу без дальнейшей помощи от меня.Вы гораздо более гибкий работник, потому что вы больше не зависите от меня.

То же самое относится к контроллерам представления (и объектам в целом);Лучше дать им все, что им нужно, чем заставить их зависеть от конкретного объекта, такого как делегат приложения.Это верно не только для контекстов управляемых объектов, но и для любой информации, которая необходима им для работы.

3 голосов
/ 31 июля 2011

Это главным образом потому, что вы хотите использовать dependency injection с вашими UIViewControllers вместо того, чтобы просто захватывать все из UIApplication, это сохраняет ваш делегат чистым, а не полным ссылочных хаков.

Это также относится к шаблону MVC:

  1. Модель

  2. View Controller (только для логики просмотра)

  3. Контроллер (для координации между видом и моделью)

2 голосов
/ 31 июля 2011

Я склонен не соглашаться с этим паттерном.

Прежде всего я пытаюсь рассматривать Базовые Данные как деталь реализации, и как любую деталь реализации она должна быть скрыта за хорошим фасадом.Фасад - это интерфейсы, которые я выставляю для своих модельных объектов.Например, если у меня есть два объекта модели;Cource и Student, любой курс может иметь несколько студентов.Я не хочу, чтобы контроллер взял на себя обязанность устанавливать предикаты и сортировать дескрипторы, а также перепрыгивать через все циклы Core Data, чтобы получить список учеников для определенного класса.Существует совершенно правильный способ показать это в модели:

@interface Cource (StudentAccess)
-(NSArray*)studentsStortedByName;
@end

Затем раз и навсегда реализуйте уродливые вещи в классе Model.Скрытие всех сложных деталей Core Data и отсутствие необходимости передавать контексты управляемого объекта.Но как мне найти источники, это должно начаться где-то правильно?Да, это так, но вам не нужно выставлять его контроллеру.Добавление таких методов также вполне разумно:

@interface Cource (CourceAccess)
+(Cource*)caurceByID:(NSString*)courceID;
+(NSArray*)allCources;
+(NSArray*)courcesHeldByTeacher:(Teacher*)teacher;
@end

Это также помогает минимизировать зависимости между контроллерами.И уменьшение зависимости между моделью и контроллером.Предполагая, что у меня есть CourceViewController и StudenViewController, я не скрывал детали базовых данных за фасадом и хотел бы также обойти контекст управляемого объекта, и в итоге я получил бы назначенный инициализатор, подобный этому:

 -(id)initWithManagedObjectContext:(NSManagedObjectContext*)moc
                           student:(Student*)student;

В то время как с хорошим хорошим фасадом я получаю следующее:

 -(id)initWithStudent:(Student*)student;

Минимизация зависимостей за фасадами в пользу внедрения зависимостей также значительно упрощает изменение внутренних реализаций.Передача контекста управляемого объекта поощряет каждый контроллер реализовывать свою собственную логику для базовых вещей.Возьмем для примера метод studentsSortedByName.Сначала это может быть сортировка по фамилии / имени, если позже изменить на сортировку по фамилии / имени, вам придется перейти к каждому контроллеру, который отсортировал студентов, и внести изменения.Там, где хороший метод фасада требует изменения одним методом, и все контроллеры автоматически получают обновление бесплатно.

1 голос
/ 31 июля 2011

В Apple Docs стараются использовать наиболее широко применяемые и устойчивые шаблоны проектирования.Внедрение зависимостей является предпочтительным, поскольку оно обеспечивает наиболее гибкую, расширяемую, многоразовую и обслуживаемую конструкцию.

По мере усложнения приложений использование квази-синглтона, подобного парковке контекста в делегате приложения, выходит из строя.В более сложных приложениях у вас может быть несколько контекстов, привязанных к нескольким магазинам.Возможно, вы захотите, чтобы одна и та же пара view-controller / view отображала данные из разных контекстов в разное время, или вы можете получить несколько контекстов в разных потоках / операциях.Вы не можете накапливать весь этот контекст в делегате приложения.

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

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

...