3

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

第一种方式

一个看起来像的方法

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

MyObjectType 是一个枚举。

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

第二种方式

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

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

哪种方式使用代表会更好?我们与一位同事就此进行了讨论,找不到比另一种更有吸引力的方法。似乎它只是决定从解析器或委托中调用什么方法......

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

这些方法中的一种是否比另一种更好?还有其他方法吗?

4

3 回答 3

2

为什么不一起去

- (void)didReceiveObject:(NSObject *)object

然后检查类类型?

这对我来说似乎更干净,更可扩展,因为这意味着您将来可以解析其他对象而无需添加更多回调。

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

于 2011-08-03T06:58:09.017 回答
1

第一种方法:

优点:

  • 更灵活地应对未来的变化。

缺点:

  • 可能导致较大的 switch 语句或混乱的 if ... else if ... else 语句。
  • 无论如何,可能会导致一系列显式方法。
  • 需要类型转换。

第二种方法:

优点:

  • 没有类型转换。
  • 如果方法是可选的,则委托只关心它感兴趣的对象。

缺点:

  • 如果方法不是可选的并且稍后扩展接口,则所有委托都会有警告,直到实现新方法。
  • 如果方法不是可选的,那么每个委托都需要实现很多方法。

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

第三种方法:

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

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

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

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

于 2011-08-03T07:21:42.023 回答
0

这是决定。

我们将同时实现这两种方式,看看哪种方式更常用。

第一种方法是最简单和最快的,因此我们将保留它以满足内部需求。

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

由于每个回调都应该有一大块代码,所以通用的方法肯定是 rbrown 指向的大 switch 语句。

感谢您的帮助。

于 2011-08-03T11:02:55.303 回答