Модульное программирование в Какао - помогите сохранить сгруппированные ссылки - PullRequest
0 голосов
/ 20 апреля 2011

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

Проект выполняется на Какао.Сетевая часть использует Bonjour и будет публиковать сервис (самостоятельно) и искать аналогичные сервисы.Полученный массив нужно будет отправить в табличное представление, чтобы пользователи могли выбрать желаемую службу для подключения.В настоящее время это достигается с делегацией.

Моя иерархия классов, сетевая группа:

NetController        // Entrance to the networking group
Socket               // Create a socket for service (self)
Bonjour              // Bonjour manager
  BonjourPublish     // Publish a service on the network
  BonjourBrowse      // Browse for other services on the network

Проблема в том, что для делегирования для работы я должен установить ссылку на класс, который будет выполнять делегирование в представлении, чтополучить массив служб:

[[[netController bonjour] serviceBrowser] setDelegate:self];

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

  1. Как лучше всего справляться с такими проблемами?

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

Ваша помощь очень ценится!

1 Ответ

0 голосов
/ 21 апреля 2011

попробуйте протокол: http://en.wikipedia.org/wiki/Objective-C#Protocols

и реализуйте некоторый фабричный интерфейс, который может создавать и возвращать объекты, соответствующие протоколу, но специализируется для требуемой задачи / реализации.

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

@protocol MONNetworkDataProvider;

@class MONNetworkLocation;
@class MONNetworkConnectionType;

@protocol MONNetworkConnection /* among other services, this may be your Bonjour manager */

- (MONNetworkConnectionType *)networkConnectionType;

- (BOOL)isServiceAvailable;
- (BOOL)isConnected;

- (MONNetworkErrorCode)connect:(NSError**)outError;

- (NSData *)helpMeGetTheDataAThisLocation:(MONNetworkLocation *)location error:(NSError**)outError;

@end

/* this is usually used in some controller, and can be used to parse or process the results it's interested in */
@protocol MONNetworkDataRecipient

- (NSArray *)typesOfInterest; /* called by MONNetworkDataProvider. used to minimize data returned and requests */

/* MONNetworkDataProvider callbacks: */
- (void)networkRequestFailed:(NSObject<MONNetworkDataProvider>*)provider withError:(NSError *)error;
- (void)networkRequestSucceeded:(NSObject<MONNetworkDataProvider>*)provider data:(NSData *)data;

/* the remainder is useful for the controller: */
- (BOOL)hasRequestCompleted;
- (BOOL)didRequestSucceed;
- (NSError *)errorFromRequest;

/* assuming all went well: */
- (NSArray *)decodedResults;

@end

@protocol MONNetworkDataProvider /* mediates betweeen the connection and recipient. also handles threading */

- (id)initWithLocation:(MONNetworkLocation *)location recipient:(NSObject<MONNetworkDataRecipient>*)inRecipient connection:(NSObject<MONNetworkConnection>*)inConnection;

- (NSObject<MONNetworkConnection>*)connection;
- (NSObject<MONNetworkDataRecipient>*)recipient;

/* informs self.recipient when the read is complete */
- (void)readAsynchronously;

/* informs self.recipient when the read is complete */
- (void)readSynchronously;

@end

/*
    now the factory MONNetworkingFactory only needs to know about all the variants of MONNetworkConnection and MONNetworkDataProvider needed for this app.
    it creates and returns something appropriate, given the context of the arguments, day of the week, whatever else you like.
*/
@interface MONNetworkingFactory : NSObject

+ (NSObject<MONNetworkConnection>*)newMONNetworkConnectionForService(NSString * service);

+ (NSObject<MONNetworkDataProvider>*)newMONNetworkDataProviderForLocation:(MONNetworkLocation *)location recipient:(NSObject<MONNetworkDataRecipient>*)inRecipient connection:(NSObject<MONNetworkConnection>*)inConnection;

@end

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

...