如何为对象设置多个委托而不给对象太多的域知识?

时间:2010-07-30 06:31:32

标签: cocoa cocoa-touch delegates

设置:我有一个单例数据访问管理器对象,称之为Manager。我也有一些视图控制器,称它们为苹果和橘子。苹果和橘子都使用Manager来获得一些共享数据模型/访问功能。

我希望经理在某些情况下根据这样的事情回复他们中的任何一个:

if (someCondition)
    [self.applesDelegate callSomething];
else if (otherCondition)
    [self.orangesDelegate callSomething];

我看到了实现这一点的三种方式,其中没有一种我很满意。

1)完全像我上面那样做,给Manager一些属性,比如applesDelegate和orangesDelegate,并让相关的视图控制器为此注册。但那会很糟糕,因为经理会拥有领域知识,我不想拥有。经理不应该对Apple或Orange对象有任何了解。

2)拥有动态委托地图。 Manager会为委托提供一些NSMutableDictionary,而Apples和Oranges会做类似

的事情
[manager.delegateMap setObject:self forKey:@"applesDelegate"];

当需要调用代理人时,管理员会做类似

的事情
if (someCondition) {
    [[delegatemap objectForKey:@"applesDelegate"] callSomeMethod];
}

这听起来可行,但很奇怪。而且我不确定当你没有委托属性但是这种间接时,将委托设置为nil的常见dealloc要求是如何工作的。

3)完全放弃代表的想法并改为使用通知。经理只会生成通知,苹果和橘子会听取这些通知。这会丢失大量的编译时间检查,这就是为什么我仍然在考虑有更紧密耦合的代理。

你会在这推荐三个中的哪一个?或者也许是不同的东西?

1 个答案:

答案 0 :(得分:1)

在某些情况下,责任链模式很有用。每个代表都能够确定它是否可以完成任务。所以它只是

       if ( ! apple.doItIfYouCan(condition, methodName) )
       else ( orange.doItIfYouCan(condition, methodName)

我很少对代表们的责任扩散感到满意。

所以我通常会寻找类似你的选项2.实际上你正在构建一个调度表。在任何可能的情况下,我都会尝试将条件重新转换为可以在表格中查找的内容。因此,实际上我们会获取一些信息并获取对象和方法

        whatToDo = lookup(condition definition)

        whatToDo[who].what

(对于缺乏语法道歉,我不会说你的语言,我希望这些概念能够翻译 - 我可以用JavaScript,或用C中的函数指针或Java中的反射来实现。)