Это проблема, которая беспокоила меня некоторое время.Я все еще довольно новичок с некоторыми из этих шаблонов, поэтому вам придется простить меня (и исправить меня), если я неправильно использую какое-либо из этих терминов.
Моя методология
Я создал игровой движок.Все объекты в моем игровом движке используют инверсию управления для получения зависимостей.Все эти зависимости реализуют протоколы и никогда не доступны напрямую в проекте, кроме как на этапе начальной загрузки.Чтобы получить эти объекты, у меня есть концепция сервисного локатора.Задача поиска службы заключается в том, чтобы найти объект, который соответствует определенному протоколу, и вернуть его.Это очень похоже на фабрику, но она также должна обрабатывать зависимости.
Для предоставления услуг локатору службы у меня есть то, что я называю спецификаторами службы.Локатор службы знает обо всех спецификаторах службы в проекте, и когда объект запрашивается, он пытается получить экземпляр объекта, соответствующего предоставленному протоколу, от каждого из них.Этот объект затем возвращается вызывающей стороне.Что хорошо в этой настройке, так это то, что спецификатор службы также знает о локаторе службы, поэтому, если он имеет какие-либо зависимости, он просто запрашивает указатель службы для этих конкретных зависимостей.
Чтобы привести пример, у меня есть объект с именем HighScoreManager.HighScoreManager реализует протокол PHighScoreManager.В любое время, если требуется экземпляр PHighScoreManager, его можно получить, вызвав:
id<PHighScoreManager> highScoreManager = [ServiceLocator resolve: @protocol(PHighScoreManager)];
Таким образом, инверсия управления.Тем не менее, в большинстве случаев это даже не требуется, поскольку большинство классов находятся в спецификаторе службы. Если в качестве зависимости требуется PHighScoreManager, то он извлекается через локатор службы.Таким образом, у меня есть хороший плоский подход к инверсии управления.
Моя проблема
Поскольку я хочу, чтобы код из моего игрового движка был предоставлен в общий доступ, я скомпилировал его как статическую библиотеку.Это работает потрясающе для всего остального, но, кажется, немного усложняется с локатором службы.Проблема в том, что некоторые сервисы меняются в зависимости от игры.В моем примере выше счет в одной игре может быть временем, а в другой - баллами.Таким образом, HighScoreManager зависит от экземпляра PHighScoreCreator, который сообщает ему, как создать объект PScore.
Чтобы предоставить PHighScoreCreator для HighScoreManager, мне нужен спецификатор службы для моей игры.Единственный способ, которым я мог придумать, - это использовать версию отражений Какао.Покопавшись, я обнаружил, что классы можно обнаружить через NSBundle, но, похоже, нет никакого способа получить текущий пакет.Таким образом, если я хочу иметь возможность искать спецификаторы своих сервисов, мне нужно было бы скомпилировать игровую логику в отдельный пакет, а затем заставить движок найти этот пакет и загрузить его.Чтобы сделать это, мне нужно будет создать третий проект, в котором будут размещаться и код движка, и набор игровой логики, тогда как на самом деле мне бы хотелось иметь игровой проект, в котором использовалась статическая библиотека движка.
Мой реальный вопрос
Итак, после всего этого мой вопрос
- Есть ли лучший способ сделать то, что я пытаюсь сделать вКакао Touch, или
- Есть ли способ найти классы, которые соответствуют протоколу моего спецификатора сервиса из основного пакета?
Спасибо за помощь и нашли время, чтобы прочитать вопрос.
-спиральная