调用委托人的数据提供者:具体还是通用?

时间:2011-07-26 14:55:05

标签: objective-c delegation ios-3.x

我有一个XML解析器,它将解析17个不同的XML文档(我正在简化这个)。 当解析器完成其作业时,它会调用执行请求的对象。

第一种方式

一种看起来像

的方法
- (void)didReceiveObject:(NSObject *)object ofType:(MyObjectType)type

MyObjectType是一个枚举。

在这个方法中,我检查类型并将对象重定向到相应的方法。

第二种方式

我可以接收的17种对象中的每一种都有一种回调方法。

- (void)didReceiveFoo:(MYFoo *)foo
- (void)didReceiveBar:(MYBar *)bar
... and so on

使用代表的哪种方式会更好? 我们与同事讨论过这个问题,但找不到比另一个更有吸引力的方式。看起来它只是决定从解析器或委托中调用哪种方法....

即使考虑添加未来的方法/委托回调,我们也没有看到任何真正的问题。

其中一种方式比另一方好吗?还有另一种方式吗?

3 个答案:

答案 0 :(得分:2)

为什么不选择

- (void)didReceiveObject:(NSObject *)object

然后检查类类型?

这对我来说似乎更清晰,更具扩展性,因为这意味着您可以在未添加更多回调的情况下解析其他对象。

(我知道这与选项一相同,但我想指出你的第二个论点是不必要的。)

答案 1 :(得分:1)

第一种方法:

优点:

  • 对未来的变化更加灵活。

缺点:

  • 如果...... else if ...... else语句,可能导致大的switch语句或乱码。
  • 无论如何,可能会产生一系列明确的方法。
  • 需要输入类型。

第二种方法:

优点:

  • 无类型铸造。
  • 如果方法是可选的,则委托只会受到它感兴趣的对象的困扰。

缺点:

  • 如果方法不是可选的,并且接口稍后扩展,则所有代理都将发出警告,直到实现新方法。
  • 如果方法不是可选的,则可以为每个代理实现许多方法。

通常在构建委托接口时,我倾向于使用泛型来实现未来的可扩展性。更改API(尤其是使用开源代码)可能非常困难。另外,我不太明白为什么你有一个XML解析器这么做。您可能想要考虑不同的设计。 17个不同的XML文档似乎很多。除此之外,我将提出第三种方法。

第三种方法:

创建一个将字符串映射到块的字典。这些块可能是void(^BlockName)(id obj)类型。您的解析器将定义一系列字符串,这些字符串将成为各种块的键。例如,

NSString * const kFooKey = @"FooKey"; 
NSString * const kBarKey = @"BarKey";
// And so on...

创建XML解析器的人会为他们感兴趣的每个密钥注册一个块。他们只需要注册他们感兴趣的密钥,并且对未来的更改完全灵活。由于您要注册显式键/对象,因此可以在没有类型转换的情况下断言传入的类型(实质上是Design By Contract)。对于你想要的东西,这可能会过度杀戮,但我发现类似的设计在我的代码中非常有用。它结合了两种解决方案的优点。如果您想使用没有块的SDK,那么主要的缺点是。但是,块正在成为Objective-C的事实标准。

除此之外,您可能希望定义一个包含17个对象的常用功能的协议,如果您还没有这样做的话。这会将您的块类型更改为void(^BlockName)(id<YourProtocol> obj)

答案 2 :(得分:0)

这是决定。

我们将实现两者并查看哪种方式使用得更多。

第一种方式是最简单和最快速的方式,因此我们会根据内部需求保留它。

但我们可能会将此代码作为静态库提供,因此我们希望提供最少量的信息。所以我们也会坚持第二种方式。

由于每个回调应该有一大块代码,通用方式肯定是rbrown指向的大转换语句。

感谢您的帮助。