Cocoa中的模块化编程 - 帮助保持参考组合在一起

时间:2011-04-20 18:01:04

标签: cocoa cocoa-touch architecture delegates

我有一个网络部分,一些业务逻辑和逻辑上分组的视图类。我想以模块化的方式安排它们,以便以后可以用另一个网络模块替换网络部分。我不是这些概念的专家(封装等),所以目前我尝试在组内保留对相关类的引用,并且永远不要在这个组之外引用它们。

该项目在Cocoa上运行。网络部分使用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. 一般来说,我需要一些关于模块化编程的好资源。我发现这些概念非常有趣和相关。有没有人对与此相关的书籍或网络资源提出建议。

  3. 非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

尝试协议: 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

然后根据需要为提供这些服务的变体类型/实现实现这些。当发出请求时,工厂会根据参数返回适当的内容。协议可以在您的应用程序中声明您需要的所有“界面”,并且可以按照您认为合适的方式进行划分。每个实现都可以封装它们使用的类型和实现。因此,数据接收者不需要查看任何接口(当然,只要它在协议中提供)。