The Gang of Four is Wrong and You Don't Understand Delegation
saturnflyer.com
saturnflyer.com
> Delegation is a way of making composition as powerful for reuse as inheritance [Lie86,JZ91]. In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate. This is analogous to subclasses deferring requests to superclasses. But with inheritance, an inherited operation can always refer to the receiving object through the "this" member variable in C++ and "self" in Smalltalk. To achieve the same effect without delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver.
Sounds like they're perfectly clear and correct to me. As the author of the post points out the GoF don't actually show examples of delegation in the book and I don't recall them using the term much, so I don't see how they're perpetrating any misinformation here.
> In JS we can assign a prototype: the equvalent of the parent slot in Self.
No, .prototype is not equivalent to a parent slot in Self. It's closer to a traits object, I think. The unstandardized __proto__ property is equivalent to a parent slot in JS.
> Yeah, Design Patterns showed examples in Java. And Java can’t do delegation. So is that a valid argument for rewriting the meaning of a term?
Design Patterns is older than Java. Maybe later editions use it, but the original version used C++ and Smalltalk.
Otherwise, good troll post, original author. I'm sure you'll get lots of traffic and people noticing your book. Well played!
Actually, people have visited, but few have stayed to read. My goal is to clarify the concept. I did plenty of research before writing this including asking Lieberman and others about it. I first wondered how everyone's notion could be wrong and doubted that my understanding was correct.
This is a term that others have attempted to clarify as well http://javalab.cs.uni-bonn.de/research/darwin/delegation.htm...
At the same time, getting hung up on terminology and trying to mandate a definition that goes against current usage just because it's older is a fool's errand and doesn't help.
Language is a social construct. It's very important for us to have consensus and agree on what words mean so that we can communicate efficiently. At the same time, there's nothing wrong about having definitions change over time.
"Car" used to mean a two-wheeled Celtic war chariot. It wouldn't be helpful to insist that it still mean that, and it's just mean to proclaim that everyone who uses "car" to mean "automobile" is wrong and doesn't understand the idea of war chariots.
Just because Lieberman tried to give it a more refined definition in the context of OOP doesn't mean that the less refined use is incorrect. You don't get to take away my English words.
The Design Patterns book sought to clarify our language yet it has this error. I'm seeking to clarify our language.
Delegate. Verb: Entrust (a task or responsibility) to another person, typically one who is less senior than oneself: "he delegates routine tasks".
It's not hard to see how that would be analogous to a variety of situations in computing.
If you want a term to be more pure, think of something more creative.
Edit: That's not to take away from your point that the GoF actually cited Lieberman in their use of delegation. If they misunderstood his intention, sure raise that point.
So why not argue about people using "delegation" when they just mean "forwarding"?
Here's an excerpt from my take on the 2 characteristics of consultation (or what is typically called "delegation") in my book
---- The first is the connascence of method names between collaborating objects. Connascence refers to the point and type of coupling between objects where a change in one object requires a change in the other. Consultation occurs when the message recipient forwards a message to another object which handles the response to the same message. A calculator would receive a balance message and forward that message to an account which responds to balance. Rails’ implementation of delegate does include a caveat that the message might be prefixed before it is forwarded, but the implementation is still connascent by method name. The second aspect of consultation is that the message recipient makes no modifications to the algorithm for handling the response. ----
I wrote to Lieberman to ask his opinion and he sided with NOT introducing the "consultation" term. But his reason was not because our misguided understanding of delegation is correct, his reason was because we already have a name for this: forwarding. The quote above is from my argument about why I think it is valuable to use the term "consultation".
So did "inheritance" but it means something very specific in programming parlance.
The language doesn't need clarifying, because the term has a definition, which is perfectly clear. Through a quirk of history, this perfectly clear definition happens to be different than the other perfectly clear definition which preceded it. Due to this retcon, Leiberman's original definition ends up being incorrect. Wasn't the first time something like this happens, and it won't be the last. So it goes.
If his post persuades everyone and they start using it the way he wants them to, then language does work that way.
I fail to see how this deserves any upvotes.
One of the points of design patterns is to define a common language. The benefit of this is that it helps people understand one another. The fact that delegation as discussed in GoF is what everyone understands delegation to be is good enough reason to continue using the word "delegation" that way and to force him to find a new word for what he wants to say. Even if his definition was first.
But his definition was NOT first. Sure, someone may have first used the term in OO programming in his sense of the word. But the word "delegation" has long-standing usage in the English language. It means, "Doing this is now your responsibility." In English there is no automatic implication that the person to whom things are delegated necessarily has access to the person who did the delegating. In practice, of course, there is. Which is why the software analogs include that. But in the real world it is clear when you intend to refer a question back to the original person, and when you do not. Therefore the long established and universally understood definition does NOT indicate that the person to whom you delegate has the option of choosing to intercept any and all questions you ask.
So which behavior is preferable?. If I delegate to you, and then need to be aware of all of the methods that you define, all of your methods, both public and private, become part of the surface of the API between us. However the whole point of modularity is to have limited APIs between you and your components. Enlarging the API may be easier and more convenient, but it entwines code into spaghetti and is bad for your code base. So good software design says that of the two possible definitions of "delegation" we are comparing, we should prefer the one that makes it clear in the delegated to method when exactly it intends to go back to the delegated object versus when it is trying to send messages to itself. And the version that does that is the version that the Gang of Four used.
Therefore he is wrong to say that delegation should be redefined to mean what he means. He is wrong to say that his definition is better grounded in the history of the word "delegation". And he's dead wrong that implementing his version of the word "delegation" is better software design than the current definition.
You are insisting at this point that we should only use the first definition ever proposed for the word in software at this point. That would be redefining it. It would also create confusion.
I do not dispute that GoF already redefined the word. That's historical fact. However what they defined it as is a concept that is better software design than the thing defined in the historical definition that you want us to go back to. Thus what they are calling delegation is not just different, but better.
To reduce jargon, it is good that we try to limit how many words get special meanings in software. And it is therefore good to only give that treatment to particularly useful concepts. Which means to me that what GoF defined "delegation" to be is more deserving of having its own word than the original concept.
Hopefully that clarifies why I call your attempt to go back to the original definition "redefinition", and why principles of good software design make the GoF definition more compelling.
If you look at the details of the patterns as examples rather than definitions, and treat on the book as a general description of common situations, problems and approaches, then all is well.
The rest is details.
This whole "object-orientation" bent in the Ruby community lately just feels like a crusade, with people thumping on old OO books, each proclaiming theirs is the "true way". And, usually, like in this example, it doesn't even matter because their code ends up doing exactly the same thing with little real-world gains in readability or ease of understanding.
I had never heard of this distinction, however it immediately made sense to me because I've run into this case in Ruby where using a ruby "delegate" object actually was much more verbose than I had envisioned because of all the context I had to bring over to the delegate object one way or another. In the event I decided "delegation" was not right because the implementation necessarily violated the Law of Demeter.
So yeah I think pragmatically it does matter.
I think we've failed then since we've totally overloaded and confused basic concepts such as weak/strong typing and dynamic/static typing.
To make matters worse, those are cases where we as programmers invented to terminology at hand and didn't just appropriate it into a programming context.
In this case a distinction is being drawn that would make "delegation" mean something that is worse from the point of view of good software design, which would leave the thing that is better software design without its commonly understood name. Doing this would create negative value.
That says that delegation as defined by GoF does more to promote modularity than the original definition, and therefore is more often going to be preferred in good software design over that defined by the article.
This is not to say that there aren't cases where what the article promotes is not convenient. Violating modularity is usually convenient. But that is a convenience that we should always be wary of.
if you have a book to sell just say so, so we can directly skip your post.
I had an interface Repo, with methods getA() and getB(). I wanted to overlay a transparent cache a la Proxy (http://en.wikipedia.org/wiki/Proxy_pattern, note its use of "delegate" in its description).
So I had implementations CachingRepo and DataStoreRepo, the first would cache recent calls and the latter would make real calls. CachingRepo would have an instance of Repo that it delegates to on a cache miss.
The issue was that DataStoreRepo.getA() relied on getB(). In a non-Lieberman delegation strategy, that B would always come from the data store, not my cache.
If I understand correctly, in Lieberman delegation getB() could return the cached values, because its "self" would point to the CachingRepo, not "this" in a Java sense.
It's not impossible to do this in Java, there's just not language support for it. The wiring would be cumbersome. Thanks for introducing me to Lieberman's work, but I'll stick with the de facto standard usage of "delegation".
The only safe way I can see this being done is by adding a reference to object A when calling/forwarding a method on object B. But that's just forwarding with extra data.
Maybe I haven't worked enough with fully dynamic languages, but I don't really see much or any benefit to doing 'Lieberman' delegation, over and above other options.
It seems like the Ruby libraries cited are the real issue, rather than a fundamental misconception of the concept of delegates or indeed inversion of control as a whole.
Always witty, and always far away from their evading (and silver :)) target...
PaulGraham said "Peter Norvig found that 16 of the 23 patterns in Design Patterns were 'invisible or simpler' in Lisp." http://www.norvig.com/design-patterns/