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!
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.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.
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.
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.
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.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).