代表们 - 他们真的是什么?

时间:2011-05-27 05:23:49

标签: iphone objective-c delegates

任何人都可以解释他们使用类比现实生活过程 - 比如运行一个棒球队,或者一个咖啡店,或者一个Auto-Mechanic's Shop - 什么都会让人感觉到什么? 就像我们甚至不能谈论CODE,SYNTAX或编程一样 - 我已经看过很多这些帖子而且没有一个真的为我做过 - 我们可以先谈谈概念吗?

就像我甚至不明白为什么我们拥有它们,它们如何有利,等等。

向我展示使用和不使用委托的流程运行的真实世界类比,因此我可以看到是什么让它们如此有用和伟大。

然后我们就可以编码了。

(仅供参考,我特别感兴趣的是Objective-C / iPhone App开发实施 - 但我认为首先从概念上理解这一点更为重要。)

提前感谢!

6 个答案:

答案 0 :(得分:8)

并非所有编码抽象都具有现实生活中的等价物。例如,你很难找到分页内存的真实比喻。因此,我不打算做一个真实的比喻,而是要给你一个真实案例,告诉你为什么需要它们。

首先,动词的实际定义(来自牛津词典):

  委托(任务或责任)来   另一个人,通常是一个人   不比自己高:他   委派例行任务|动力   委托给他的人绝对不能   误用。

委托是委派责任的对象,因为从设计的角度来看,单个类完成所有工作是没有意义的。

假设您有一个UI表类。您希望使其可重复使用以显示多种数据:这意味着,大多数情况下,您无法将其与模型本身联系起来。例如,如果您专门创建了UI表格以显示相册对象(带有名称,艺术家等),那么您将无法重复使用它来显示文件对象(具有所有者,文档类型)等等):你必须编辑课程以使其适合。这会复制很多代码,所以你应该找到另一种机制。这导致了一个问题:如果不允许绑定到数据类,它如何显示任何类型的数据?

解决方案是分担获取数据和显示数据的责任。由于您的表需要显示数据但却无法自己发现,因为它对您的模型一无所知,因此应该委托将此职责委托给另一个专门为此目的而设计的类,并将其设为信息以一般形式返回,表格将知道如何使用。

这意味着你将拥有另一个类,它将响应表对象将使用的一定数量的方法,就像它是其核心行为的一部分一样(例如,委托上获取名称的方法)列,另一个获取特定行等)。有关具体示例,您可以查找NSTableViewDelegate协议引用:这些是NSTableView可以调用其委托以获取有关各种事物或自定义行为的信息的方法。 (tableView:参数基本上每个方法都标识了调用方法的表视图。它经常被忽略,因为存在许多表视图委托类来支持单个表视图。)

代表是简单“知道更好”的对象。您的UI表格不知道如何获得它所需要的东西,但它有一个“知道更好”的委托,因此它可以从中请求数据。

您还可以使用此模式处理事件:例如,单击视图时,它不知道该做什么,但可能有一个知道该做什么的委托。

换句话说,委托是扩展类行为的几种方法之一,无需修改或继承它。

答案 1 :(得分:5)

  

他们真的是什么?

专家


顾客:嗨 - 你修好了我的车吗?

员工:我估计我们有机会在不到一个小时的时间内查看它。我准备好的时候会打电话给你。

顾客:我已经等了30分钟,我真的很匆忙!

员工:我们在一年中的这个时候非常忙碌。

客户:你似乎忙;你一直都在前台!

员工:我不是机械师。我是经理。你还想要我刹车吗?


经理擅长他的所作所为;他详细说明了客户的问题,订单闪烁流畅,制定时间表,以及工资单。虽然他喜欢汽车并对他们了解很多,但他并不是修理汽车的专家。经理能够在商店做很多事情,但是具有修复客户刹车所需专业知识的机制。

使用委托的最常见原因之一是避免子类化(这就像将经理发送到学校成为机制 - 这类似于多重继承)。当子类化可用于专门化时,通常可以使用委托。代表团是一个更宽松的债券,其中(在一个好的设计中)一个对象履行了所有或大部分的职责,但其职责的其他专业部分经常留给其他实施(代表)。

答案 2 :(得分:2)

委托是一种设计模式。在Cocoa和Cocoa Touch中,某些框架类实现了这种模式,因此您不需要对它们进行子类化来修改它们的行为。

委派的一个典型示例是决定是否应该关闭窗口。当用户点击关闭按钮时,窗口的委托将获得-windowShouldClose:,如果窗口不包含任何可能要保存的编辑,则可以返回YES,如果要为用户提供,则返回NO在关闭窗口之前保存文档的机会。

在另一个示例中,NSStream对象接收数据,但它不实现任何对该数据执行任何操作的行为。它使用委托模式;当数据可供读取时,它会向其代理发送一条消息,告诉它数据可用。然后,代理可以对传入的数据进行操作,并告诉NSStream继续侦听更多数据,或者关闭连接。

答案 3 :(得分:2)

代表有点像助手。您的助理将接听您的电话/电子邮件,在您和其他人之间来回传递消息。他/她还可以收集您需要的东西,如用品或信息。在编程中,代表更有用。人们可以自己学习新的能力,但程序却不能。相反,您创建一个执行常规功能的对象,并使用委托来执行专门的工作。这样,您可以尽可能多地重用代码,同时覆盖尽可能多的用例。委托将从对象获取消息,告诉它有关操作的状态,以及根据需要提供和接收数据。

答案 4 :(得分:2)

简而言之,代表是某项任务的专家。

作为一个真实世界的比喻,考虑拥有和经营一家有几名员工的面包店的人。经营面包店的人对烘焙有很高的了解,并按照特殊配方做基本的蛋糕,但她的主要工作是管理进来的蛋糕和糕点的订单,确保它们处理得很好。

当一个结婚蛋糕的订单进来时,店主会相应地准备面团和基本蛋糕,然后委托实际烘焙给专业制作婚礼蛋糕的糕点师,以制作所有细节和结冰。

在另一种情况下,面包店的跑步者可能会收到一份有特殊要求的蛋糕订单。他知道,她可以处理所有基本的东西,但必须与他的员工核实,告诉她是否可以满足这一要求:首先,他问她的糕点师,他是否可以处理,也许她需要什么。然后他问她的会计师,他们是否有所有这些成分库存或能及时得到它们。因此,决定是否可以满足请求,委派给员工。

现在用一个UITableView替换面包店的跑步者,用id <UITableViewDelegate>取代糕点师,用id <UITableViewDataSource>取代会计师,我们回到谈论代码。

答案 5 :(得分:1)

您可以将代表描述为董事会成员的秘书。让我们看看接听电话并保持他的议程/会议。

任何人(超级?;))都可以接听电话广告预约。但每个像你或我一样的人,都是以自己的方式做到的。这意味着我有一个anwserPhoneWithMood :( HumanMood *)心情;功能与你的不同。

现在所有董事会成员都会有这个,但他们在工作时不能为此烦恼,因为他们有其他事情可做,我们不想让他们担负这些卑鄙的任务。此外,通常不清楚呼叫的对象是谁,或者多人需要参加同一会议。在这里,我们进入秘书,她知道如何处理所有不同的电话,安排约会,并有整个董事会的概述。

让她为我们(代表)接听电话不仅有用,而且我们希望她接听所有电话,以便她保持概览,这些电话是她正常工作所需的信息。此外,对董事会成员的任何要求都是以相当通用的方式处理的,因此没有必要让每个董事会成员都以自己的方式来做。

显然,在这种情况下,秘书是代表。

希望这能让你更清楚。