14

我正在处理一些异步通信情况(事件驱动的 XML 解析、NSURLConnection 响应处理等)。我将尝试简要解释我的问题:

在我当前的场景中,有一个服务提供者(可以与 xml 解析器对话或进行一些网络通信)和一个客户端,可以要求服务提供者异步执行它的一些任务。在这种情况下,当服务提供者完成其处理时,它必须将结果传回给客户端。

我正在尝试找到一种模式或经验法则来实现这种事情,我看到了 3 种可能的解决方案:

1.使用委托模式:客户端是服务提供者的委托,任务完成后会收到结果。

2. 使用目标/动作方法:客户端要求服务提供者执行一项任务并传递一个选择器,一旦完成任务,服务提供者必须调用该选择器。

3.使用通知

更新)在尝试解决方案#2(目标和行动)一段时间后,我得出的结论是,就我而言,最好使用委托方法(#1)。在我看来,以下是每个选项的优缺点:

委托方式:

  • 1 (+)选项 1 的好处是我们可以检查编译时错误,因为客户端必须实现服务提供者的委托协议。

  • 1 (-)这也是一个缺点,因为它导致客户端与服务提供者紧密耦合,因为它必须实现其委托协议。

  • 1 (+)它允许程序员轻松浏览代码并找到客户端的什么方法,服务提供者正在调用以传递其结果。

  • 1 (-)从客户端的角度来看,一旦有结果,服务提供者将调用什么方法并不容易。这仍然很容易,只需转到委托协议方法就可以了,但#2 方法更直接。

  • 1 (-)我们必须编写更多代码:定义委托协议并实现它。

  • 1 (-)此外,委托模式实际上应该用于委托行为。从语义上讲,这种情况不会是委托的确切情况。

行动/目标方法

  • 2 (+)选项 2 的好处是,在调用服务提供者方法时,还必须指定指定回调操作的 @selector,这样程序员就知道将调用哪个方法来处理结果。

  • 2 (-)与此相反,在浏览服务提供者代码时,很难找到客户端会回调哪个方法。程序员必须转到服务调用并查看正在传递的@selector。

  • 2 (+)这是一个更动态的解决方案,并且减少了部件之间的耦合。

  • 2 (-)也许是最重要的事情之一:它可能导致运行时错误和副作用,因为客户端可以将不存在的选择器传递给服务提供者。

  • 2 (-)使用简单和标准的方法 (#performSelector:withArgument:withArgument:) 服务提供者最多只能传递 2 个参数。

通知:

  • 我不会选择通知,因为我认为它们应该在需要更新多个对象时使用。另外,在这种情况下,我想直接告诉委托/目标对象在构建结果后要做什么。

结论:在这一点上,我会选择委托机制。这种方法提供了更高的安全性,并允许轻松浏览代码以跟踪向委托发送服务提供者操作的结果的后果。这个解决方案的消极方面是:它是一个更静态的解决方案,我们需要编写更多代码(与协议相关的东西),并且从语义上讲,我们并不是真正谈论委托,因为服务提供商不会委托任何东西.

我错过了什么吗?你推荐什么,为什么?

谢谢!

4

3 回答 3

3

你确实错过了第三个选项——通知。

您可以让客户观察来自服务提供商的通知,表明它有新数据可用。当客户端收到此通知时,它可以使用来自服务提供者的数据。

这允许良好的松散耦合;不过,有些决定取决于您是否需要推/拉系统。

于 2009-12-22T19:54:24.687 回答
0

非常好的问题。

我认为我还没有资格(因为我是新手)来评论哪种设计模式比另一种更好。但只想提一下,您在第 2 点(运行时异常)中提到的缺点可以通过

if([delegate respondsToSelector:callback]){
    //call to callback here
}

希望这有助于权衡选择

于 2009-12-22T19:00:12.570 回答
0

委托方法的另一个缺点:服务提供商只能有一个委托。如果您的服务提供者是单例的,并且您有多个客户端,则此模式不起作用。

这让我选择了行动/目标方法。我的服务提供者持有状态并在多个客户端之间共享。

于 2010-07-06T13:28:29.797 回答