Дизайн: передача экземпляров классов или использование синглетонов? - PullRequest
3 голосов
/ 04 ноября 2010

Мой проект приложения содержит несколько вспомогательных классов, которые обслуживают все виды различных целей (например, время / дата / расчет, доступ к БД, ..). Инициирование этих классов довольно дорого, так как они содержат некоторые свойства, которые должны быть заполнены из базы данных или должны быть пересчитывается каждый раз, когда создается новый экземпляр. Чтобы избежать производительности Проблемы, которые я склонен инициировать каждый из этих классов в приложении делегата и передать их из viewController в viewController.

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

Ответы [ 5 ]

4 голосов
/ 04 ноября 2010

Проблема синглетонов состоит в том, что они затрудняют насмешку и юнит-тестирование вашего приложения. Вы должны отделить свои зависимости; и если вам как-то нужен синглтон (который должен быть очень, очень редким), тогда подумайте о том, чтобы синглтон реализовал интерфейс, который вы можете использовать для тестирования.

1 голос
/ 04 ноября 2010

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

1 голос
/ 04 ноября 2010

Синглтоны - это, в основном, глобальные переменные, и создавать глобальную переменную просто плохая идея, чтобы избежать ее передачи. Опять же, часто правильная вещь - просто передавать объекты из одного класса в другой. Хитрость заключается в определении минимального количества данных, которые вы можете передать, чтобы минимизировать связь. Это где хорошо продуманные классы важны. Например, вам редко нужно передавать NSManagedObjectContext, потому что вы можете получить его из любого NSManagedObject.

Теперь позвольте мне рассмотреть конкретный случай ваших дорогостоящих объектов. Вы можете попробовать объединить эти объекты вместо того, чтобы создавать их каждый раз, когда это необходимо. Доступ к базе данных является хорошим примером этого. Вместо того, чтобы выделять соединение с базой данных каждый раз, когда вы запрашиваете одно, вы извлекаете одно из кэша. Конечно, когда кеш пуст, вам нужно выделить его. И по соображениям памяти вы должны быть готовы и способны очищать кеш, когда система запрашивает об этом.

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

1 голос
/ 04 ноября 2010

Всякий раз, когда у меня возникает желание использовать синглтон, я перечитываю Глобальные переменные - это плохо и думаю, действительно ли удобство стоит мириться с этим (слегка) перефразированным списком проблем:

  • Нелокальность методов и переменных
  • Нет контроля доступа или проверки ограничений
  • неявная связь
  • Проблемы параллелизма
  • Загрязнение пространства имен
  • Проблемы с выделением памяти
  • Слишком сложное тестирование
0 голосов
/ 04 ноября 2010

Лично я обычно пользуюсь синглтоном.
На мой взгляд, это делает код чище ...

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

Редактировать: Кажется, я ошибаюсь!
как насчет гибкой реализации?

static Singleton *sharedSingleton = nil;

+ (Singleton*)sharedManager
{
  if (sharedSingleton == nil) {
    sharedSingleton = [[super alloc] init];
  }
  return sharedSingleton;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...