To jest problem, który od pewnego czasu mnie dręczy. Wciąż jestem całkiem nowy z niektórymi z tych wzorców, więc będziesz musiał mi wybaczyć (i poprawić), jeśli użyjesz któregoś z nich niepoprawnie.Jak mogę wdrożyć wzorzec lokalizatora usług w programie Cocoa Touch w wielu projektach?
My Metodologia
Utworzyłem silnik gry. Wszystkie obiekty w moim silniku gry wykorzystują inwersję kontroli w celu uzyskania zależności. Wszystkie te zależności implementują protokoły i nigdy nie są dostępne bezpośrednio w projekcie, inne niż podczas fazy ładowania. Aby uzyskać te obiekty, mam koncepcję lokalizatora usług. Zadaniem lokalizatora usług jest zlokalizowanie obiektu zgodnego z określonym protokołem i zwrócenie go. To bardzo przypomina fabrykę, ale powinno również obsługiwać zależności.
Aby zapewnić usługi lokalizatorowi usług, mam to, co nazywam specyfikatorami usług. Lokalizator usługi zna wszystkie specyfikatory usług w projekcie, a gdy obiekt jest żądany, próbuje uzyskać instancję obiektu zgodną z dostarczonym protokołem z każdego z nich. Obiekt ten jest następnie zwracany do osoby dzwoniącej. To, co jest fajne w tej konfiguracji, to specyfikator usługi, który również zna się na lokalizatorze usług, więc jeśli ma jakieś zależności, po prostu pyta o lokalizator usług dla tych konkretnych zależności.
Aby podać przykład, mam obiekt o nazwie HighScoreManager. HighScoreManager implementuje protokół PHighScoreManager. W dowolnym momencie, jeśli wymagana jest instancją PHighScoreManager, może być pobrana przez wywołanie:
id<PHighScoreManager> highScoreManager = [ServiceLocator resolve: @protocol(PHighScoreManager)];
Zatem odwrócenie sterowania. Jednak w większości przypadków nie jest to konieczne, ponieważ większość klas znajduje się w specyfikatorze usług, jeśli jeden z wymaganych PHighScoreManager jest zależny, jest on pobierany za pośrednictwem lokalizatora usług. Tak więc mam ładne płaskie podejście do odwrócenia kontroli.
mój problem
Bo chcę kod z moim silniku gry mają być dzielone, mam to skompilowane jako statyczne biblioteki. Działa to niesamowicie dla wszystkich innych elementów, ale wydaje się, że jest trochę trudny z lokalizatorem usług. Problem polega na tym, że niektóre usługi zmieniają się w zależności od gry. W powyższym przykładzie wynik w jednej grze może być czasem, w innym może to być punkt. Tak więc, HighScoreManager zależy od instancji PHighScoreCreator, która mówi, jak utworzyć obiekt PScore.
W celu udostępnienia programu PHighScoreCreator na HighScoreManager, potrzebuję specyfikatora usługi dla mojej gry. Jedynym sposobem, w jaki mogłem o tym pomyśleć, było użycie wersji odbicia Cocoa. Po przekopaniu okazało się, że klasy można odkryć przez NSBundle, ale wydaje się, że nie ma sposobu na pobranie aktualnego pakietu. Tak więc, jeśli chcę móc wyszukiwać moje specyfikatory usług, będę musiała skompilować logikę gry do własnego pakietu, a następnie sprawię, że silnik przeszuka ten pakiet i załaduje go. W tym celu musiałbym stworzyć trzeci projekt zawierający zarówno kod silnika, jak i pakiet logiczny gry, podczas gdy w rzeczywistości chciałbym mieć projekt gry wykorzystujący statyczną bibliotekę silnika.
Moje Prawdziwe pytanie
Więc po tym wszystkim, że moje pytanie jest
- Czy istnieje lepszy sposób, aby robić to, co staram się osiągnąć w Cocoa Touch lub
- Czy istnieje sposób na wykrycie klas zgodnych z protokołem specyfikacji usług z głównego pakietu?
Dzięki za pomoc i poświęcenie czasu na przeczytanie pytania.
-helixed
Próbowałem iść tą ścieżką, a problem polega na tym, że nie możesz wiedzieć z wyprzedzeniem, jakie nazwy klas będą zawarte w pakiecie. Dlatego nie można wykonywać iteracji po wszystkich klasach w pakiecie. – LandonSchropp
Edytowałem odpowiedź, aby podać kilka sugestii co dalej robić po wystąpieniu NSBundle. Mam nadzieję że to pomoże. :-) –
Mam przeczucie, że może to nie być dozwolone w aplikacji na iPhone'a, ale mogę się mylić. Jestem całkiem pewny, że Apple nie chce, abyś ładował klasy w czasie wykonywania na telefonie iPhone. Ale świetne pytanie. –