我有一个XML解析器,它将解析17个不同的XML文档(我正在简化这个)。 当解析器完成其作业时,它会调用执行请求的对象。
第一种方式
一种看起来像
的方法- (void)didReceiveObject:(NSObject *)object ofType:(MyObjectType)type
MyObjectType是一个枚举。
在这个方法中,我检查类型并将对象重定向到相应的方法。
第二种方式
我可以接收的17种对象中的每一种都有一种回调方法。
- (void)didReceiveFoo:(MYFoo *)foo
- (void)didReceiveBar:(MYBar *)bar
... and so on
使用代表的哪种方式会更好? 我们与同事讨论过这个问题,但找不到比另一个更有吸引力的方式。看起来它只是决定从解析器或委托中调用哪种方法....
即使考虑添加未来的方法/委托回调,我们也没有看到任何真正的问题。
其中一种方式比另一方好吗?还有另一种方式吗?
答案 0 :(得分:2)
为什么不选择
- (void)didReceiveObject:(NSObject *)object
然后检查类类型?
这对我来说似乎更清晰,更具扩展性,因为这意味着您可以在未添加更多回调的情况下解析其他对象。
(我知道这与选项一相同,但我想指出你的第二个论点是不必要的。)
答案 1 :(得分:1)
第一种方法:
优点:
缺点:
第二种方法:
优点:
缺点:
通常在构建委托接口时,我倾向于使用泛型来实现未来的可扩展性。更改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指向的大转换语句。
感谢您的帮助。