代表们——他们到底是什么?
有人能用一些现实生活流程的类比来解释它们吗——比如经营一支棒球队、一家咖啡店或一家汽车修理店——任何有意义的事情? 就像我们甚至不要谈论代码、语法或编程——我看过很多这样的帖子,但没有一个真正适合我——我们可以先谈谈概念吗?
就像我什至不明白为什么我们有它们,它们有什么优势,等等。
向我展示在有和没有委托的情况下运行的流程的真实世界类比,这样我就可以看到是什么让它们如此有用和伟大。
然后我们就可以将其编码出来。
(仅供参考,我的具体兴趣是 Objective-C/iPhone 应用程序开发实现 - 但我真的认为首先从概念上理解这一点更为重要。)
提前致谢!
Can anyone out there explain them using analogies to some real-life processes - like running a Baseball team, or a coffee shop, or an Auto-Mechanic's Shop - anything that would MAKE SENSE?
Like lets not even talk CODE, or SYNTAX, or programming - I've seen plenty of those posts and none of them really do it for me - can we just talk concepts first?
Like I don't even understand WHY we have them, how they're advantageous, etc.
Show me the real-world analogy of a process run with and without delegates, so I can see what makes them so useful and great.
Then we can code-it-out.
(And FYI, my specific interest is in Objective-C/iPhone App Development implementation - but I really think understanding this conceptually first is much more important.)
thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
并非所有编码抽象都有现实生活中的等价物。例如,您很难找到现实生活中的分页内存的类比。因此,我不会在现实生活中进行类比,而是会给您一个现实生活中的案例来说明为什么您需要它们。
首先,动词委托的实际定义(来自牛津词典):
委托是被委派责任的对象,因为从设计角度来看,让一个类完成所有工作是没有意义的。
假设您有一个 UI 表类。您希望使其可重用以显示多种数据:这意味着,在大多数情况下,您不能将其与模型本身联系起来。例如,如果您专门制作 UI 表来显示专辑对象(具有名称、艺术家等),那么您将无法重用它来显示文件对象(具有所有者、文档类型)等):您必须编辑该类以使其适合。这会重复很多代码,所以你应该找到另一种机制。这导致了一个问题:如果不允许绑定到数据类,它如何显示任何类型的数据?
解决方案是分离获取数据和显示数据的责任。由于您的表需要数据来显示它,但无法自行发现它,因为它对您的模型一无所知,因此它应该将此责任委托给另一个类,该类专门为此目的而设计,并掌握它以表格知道如何使用的通用形式返回信息。
这意味着您将拥有另一个类,该类将响应表对象将使用的一定数量的方法,就好像它是其核心行为的一部分一样(例如,委托上的一个方法用于获取列的名称,另一个方法是获取特定行等)。对于具体的示例,您可以查找
NSTableViewDelegate
协议参考:这些是NSTableView
可以调用其委托来获取有关各种事物或自定义行为的信息的方法。 (tableView:
参数基本上每个方法都标识了调用该方法的表视图。它经常被忽略,因为存在许多表视图委托类来支持单个表视图。)委托是简单地“更了解”的对象”。您的 UI 表不知道如何获取所需的数据,但它有一个“更了解”的委托,因此它可以从中请求数据。
您还可以使用此模式来处理事件:例如,当单击视图时,它不知道要做什么,但也许它有一个知道要做什么的委托。
换句话说,委托是在不修改类或子类化类的情况下扩展类行为的几种方法之一。
Not all coding abstractions have a real-life equivalent. For instance, you'd be hard pressed to find a real-life analogy for paged memory. So instead of making a real-life analogy, I'm just going to give you a real-life case of why you need them.
First things first, the actual definition of the verb to delegate (from the Oxford Dictionary):
Delegates are objects that are delegated a responsibility, because it didn't make sense from a design perspective to have a single class do all the job.
Let's say you have a UI table class. You want to make it reusable to display many kinds of data: that means, for the most part, that you can't tie it to your model itself. For instance, if you made your UI table specifically to display Album objects (with a name, an artist, etc.) then you wouldn't be able to reuse it to display, say, File objects (with an owner, a document type, etc.): you'd have to edit the class to make it fit. This will duplicate a lot of code, so you should find another mechanism. This leads to a problem: how can it display any kind of data if it's not allowed to tie to the data classes?
The solution is to split the responsibility of getting the data and displaying the data. Since your table needs the data to display it but can't discover it itself because it knows nothing about your model, it should delegate this responsibility to another class, crafted precisely for this purpose, and have it hand the information back in a general form that the table will know how to use.
This means you'll have another class that will respond to a certain number of methods that the table object will use as if it was part of its core behavior (for instance, a method on the delegate to get the name of the columns, another to get a specific row, etc.). For a concrete example, you could look up the
NSTableViewDelegate
protocol reference: these are the methodsNSTableView
can call on its delegate to get information about various things or customized behavior. (ThetableView:
argument basically every method has identifies the table view calling the method. It's often ignored as many table view delegate classes exist to support a single table view.)Delegates are objects that simply "know better". Your UI table has no clue how to get what it needs, but it has a delegate that "knows better", so it can request the data from it.
You can also use this pattern to handle events: for instance, when a view is clicked, it doesn't know what to do, but maybe it has a delegate that knows what to do.
In other words, delegates are one of a few ways of extending a class's behavior without modifying it or subclassing it.
专家
顾客:嗨 - 你修好了我的车吗?
员工:我估计不到一个小时我们就有机会看一下。准备好后我会打电话给你。
顾客:我已经等了30分钟了,真是着急啊!
员工:每年的这个时候我们都很忙。
顾客:你看起来不忙;你一直在前台!
员工:我不是机械师。我是经理。你还想让我修你的刹车吗?
经理很擅长他所做的事情;他为客户详细说明问题、订购闪光液、制定时间表并计算工资。虽然他喜欢汽车并且对汽车了解很多,但他并不是修理汽车的专家。经理有能力在车间做很多事情,但机械师才拥有修理客户刹车所需的专业知识。
使用委派的最常见原因之一是避免子类化(这就像将经理送到学校成为机械师 - 这个类比看起来很像多重继承)。当子类化可以用于专门化时,通常可以使用委托来代替。委托是一种较松散的联系,其中(在良好的设计中)一个对象履行所有或大部分职责,但通常将其职责的专门部分留给其他实现(委托)。
specialists
Customer: Hi - did you fix my car?
Employee: I estimate that we'll have a chance to look at it in less an hour. I'll call you when it's ready.
Customer: I've already waited 30 minutes, and I'm really in a rush!
Employee: We're very busy at this time of year.
Customer: You don't seem busy; you've been at the front desk the entire time!
Employee: I'm not a mechanic. I am the manager. Do you still want me to fix your brakes?
The manager's good at what he does; he details problems for the customers, orders blinker fluid, makes the schedule, and does payroll. Although he likes cars and knows a lot about them, he's not a specialist at repairing them. The manager's capable of doing many things at the shop, but it's the mechanics that have the expertise required to fix the customer's brakes.
One of the most common reasons delegation is used is to avoid subclassing (that would be like sending the manager to school to become a mechanic - an analogy which looks a lot like multiple inheritance). When subclassing could be used to specialize, delegation may often be used instead. Delegation is a looser bond where (in a good design) one object fulfills all or most of the duties, but leaves frequently specialized portions of its duties to other implementations (the delegates).
代表有点像助理。您的助理将接听您的电话/电子邮件,在您和其他人之间来回传递消息。他/她还可以收集您需要的东西,例如用品或信息。在编程中,委托甚至更有用。人们可以自己学习新的能力,但程序却不能。相反,您创建一个执行一般功能的对象,并使用委托来完成专门的工作。这样您就可以重用尽可能多的代码,同时覆盖尽可能多的用例。委托将从对象获取消息,告诉它操作的状态,以及根据需要提供和接收数据。
A delegate is kind of like an assistant. Your assistant will answer your phone/email, passing messages back and forth between you and other people. He/she could also gather things you need, like supplies or information. In programming, delegates are even more useful. People can learn new abilities on their own, but programs can't. Instead, you create an object which performs the general function, and use delegates to do the specialized work. This way you can reuse as much code as possible while covering as many use cases as possible. The delegate will get messages from the object telling it about the status of the operation, as well as giving and receiving data as needed.
委托是一种设计模式。在 Cocoa 和 Cocoa Touch 中,某些框架类实现了这种模式,因此您不需要对它们进行子类化来修改它们的行为。
委托的一个典型例子是决定是否应该关闭窗口。当用户点击关闭按钮时,窗口的委托将获得一个
-windowShouldClose:
并且如果窗口不包含任何可能想要保存的编辑,它可以返回 YES,如果您想要,它可以返回 NO让用户有机会在关闭窗口之前保存文档。在另一个示例中,
NSStream
对象接收数据,但它没有实现任何行为来对该数据执行任何操作。它使用委托模式;当数据可供读取时,它会向其委托发送一条消息,告诉它数据可用。然后,委托可以对传入的数据进行操作,并告诉 NSStream 继续侦听更多数据,或者关闭连接。Delegation is a design pattern. In Cocoa and Cocoa Touch, certain framework classes implement this pattern so that you don't need to subclass them to modify their behavior.
One typical example of delegation, is deciding whether a window should be closed or not. When the user hits the close button, the window's delegate will get a
-windowShouldClose:
and it can either return YES if the window doesn't contain any edits that might want to save, or NO if you want to give the user a chance to save a document before closing its window.In another example, the
NSStream
object receives data, but it doesn't implement any behavior to do anything with that data. It uses the delegation pattern; when data is available to read, it sends a message to its delegate to tell it that data is available. The delegate can then go and operate on the incoming data, and tell theNSStream
to continue listening for more data, or to close the connection.简而言之,代表是某项任务的专家。
作为一个现实世界的类比,假设某人拥有并经营一家面包店,并拥有多名员工。经营面包店的人对烘焙有很高的了解,并按照特殊配方制作基本蛋糕,但她的主要工作是管理蛋糕和糕点店的订单并确保它们得到妥善处理。
当收到婚礼蛋糕订单时,业主会相应地准备面团和基本蛋糕,并将实际烘焙工作委托给专门制作婚礼蛋糕的糕点师,由他们负责制作所有细节和糖霜。
在另一种情况下,面包店的经营者可能会收到有一些特殊要求的蛋糕订单。他知道,她可以处理所有基本的事情,但必须与他的员工核实,告诉她是否可以满足该请求:首先,他问她的糕点师,他是否可以处理这个问题,也许她需要什么。然后他问她的会计师,他们是否有所有这些原料的库存或者可以及时获得。因此,是否可以满足请求的决定权委托给员工。
现在用
UITableView
替换面包店的跑步者,用id
替换糕点师,用id
替换会计师,我们回到谈论代码。In a nutshell, a delegate is a specialist for a certain task.
As a real world analogy, consider someone owning and running a bakery with several employees. The person running the bakery has a high-level understanding of baking and does the basic cakes following the special recipe, but her main job is managing the orders for cakes and patisserie that come in and ensure they are handled well.
When an order for a wedding cake comes in, the owner prepares the dough and basic cake accordingly and delegates the actual baking to the patissier who is specialized in making wedding cakes for crafting out all the details and the icing.
In another scenario, the runner of the bakery may get an order for a cake that has some special requirements. He knows, that she can handle all the basic stuff, but has to check back with his employees to tell her whether or not that request can be fulfilled: First, he asks her patissier, whether he could handle that and maybe what she needs. He then asks her accountant, if they have all those ingredients in stock or can get them in time. So the decision of whether the request can be fulfilled, is delegated to the employees.
Now substitute the runner of the bakery with a
UITableView
, the patissier withid <UITableViewDelegate>
and the accountant withid <UITableViewDataSource>
and we're back to talking code.您可以将代表想象为董事会成员的秘书。让我们看看接听电话并保留他的议程/会议。
任何人(超级类?;))都可以接听电话广告安排预约。但像你或我一样的每个人都以自己的方式做这件事。所以这意味着我有一个 anwserPhoneWithMood: (HumanMood *) 心情;与你的功能不同。
现在所有的董事会成员也会有这个,但他们在工作时不会被它打扰,因为他们有其他事情要做,我们不想让他们承担这些琐碎的任务。此外,通常不清楚呼叫的对象是谁,或者需要多人参加同一个会议。在这里,我们轮到秘书了,她知道如何处理所有不同的电话、安排约会,并了解整个董事会的概况。
让她为我们(代表)接听电话不仅有用,而且我们希望她接听所有电话,以便她保持概览,这些电话是她正确完成工作所需的信息。此外,任何对董事会成员的要求都是以相当通用的方式处理的,因此没有必要让每个董事会成员都按照自己的方式行事。
在这种情况下,显然,秘书就是代表。
希望这能让你更清楚。
You could picture a delegate as a board members's secretary. Lets look at answering the phone and keeping his agenda/meetings.
Any human being (super class? ;) ) can answer a phone ad schedule an appointment. But every single human being like you or me, does it in their own way. So that means I have a anwserPhoneWithMood: (HumanMood *) mood; function that is different from yours.
Now all the board members would have this too, but they cant be bothered with it when they are at work, because they have other things to do, we dont want to burden them with these menial tasks. Also, often it is not clear for whom the call is meant, or multiple people need to attend the same meeting. Here we enter the secretary, she knows how to handle all the different calls, schedule appointments, and has the overview for the whole board.
Not only is it useful to have her answer the phone for us (delegate) but we want her to answer all the calls, so that she keeps the overview, these calls are information she needs to do her job properly. Also, any calls for a board member is handled in a rather generic way, so there is no need to have every board member doing it their own way.
In this case obviously, the secretary is the delegate.
Hope this makes it clearer for you.