

The Gang of Four is Wrong and You Don't Understand Delegation - angelbob
http://www.saturnflyer.com/blog/jim/2012/07/06/the-gang-of-four-is-wrong-and-you-dont-understand-delegation

======
munificent
From Design Patterns (first edition):

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

~~~
saturnflyer
Thanks for clarifying. I had most of it written before posting and had
forgotten the code samples. My copy of Design Patterns is packed up for a
move. I've update it to refer to C++.

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...](http://javalab.cs.uni-
bonn.de/research/darwin/delegation.html)

~~~
scott_s
If you agree with munificent, then perhaps you could soften your title and
introduction to say that many people confuse what the GoF meant, not that the
GoF are wrong.

~~~
saturnflyer
good point. I'll verify the citation and update it.

------
btilly
The td;lr of this post: this article is misguided according to usage, the
history of the word "delegation", and the principles of good software design.

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.

~~~
saturnflyer
I never said delegation should be redefined. In fact I'm pointing out that the
GoF did the redefining. In the history of Object-oriented programming
"delegation" means what it was described to be. I never said that any
particular implementation is "better software design". Please show me where
you got these things that I supposedly said.

~~~
btilly
You admit that today in common usage and implementation in various languages,
"delegation" means what the GoF described it as. Language is defined by usage,
so that is 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.

------
peeters
Delegation is such a commonly-used English word that you don't _get_ to have a
monopoly on its definition. If I have two classes and one delegates to an
instance of the other, then it's delegation.

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.

~~~
saturnflyer
Lieberman invented this term. It did not exist prior to his work. I have
confirmed this with Lieberman himself as well as Jim Coplien and David Ungar.

The Design Patterns book sought to clarify our language yet it has this error.
I'm seeking to clarify our language.

~~~
peeters
He did not invent the term. "Delegate" and "delegation" have been around a lot
longer than computers. Here's a definition:

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.

~~~
saturnflyer
In programming terms, he did. I appreciate that it is an English language word
and was initially what I thought it meant. But when he applied the term he
meant it specifically. Otherwise, we already have a term for this: forwarding.

So why not argue about people using "delegation" when they just mean
"forwarding"?

~~~
peeters
Alright, let's take it for a spin. What do you call the thing that you're
forwarding to? The endpoint? The "nextLinkInChain"? Delegate seems pretty
natural to me in most domains, but as you say, I've been poisoned by GoF.

~~~
saturnflyer
I'm planning to follow up in another post, but Gunther Kniesel coined the term
"consultation" ([http://javalab.cs.uni-
bonn.de/research/darwin/delegation.htm...](http://javalab.cs.uni-
bonn.de/research/darwin/delegation.html)) and I've used a generic "attendant"
term to refer to the other object.

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".

------
jonathanyc
So he's redefining delegation in your own sense (implied by his strange
titlebait "The Gang of Four is Wrong") and then criticizing everyone else post
hoc?

I fail to see how this deserves any upvotes.

~~~
saturnflyer
I'm the author. I'm not redefining delegation. I'm pointing out that the Gang
of Four, who cited Henry Lieberman who created the term, described it
incorrectly. You can read the citations in the Design Patterns book and see
exactly what they got wrong. Here's a link to Lieberman's work
[http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/De...](http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html)

------
Jare
Many people agree on the words proposed by GoF, but not on the details of the
meaning, and this is a frequent source of misunderstandings and useless
debates. Over the years I have gone from fan of the book to considering it a
net negative force in software engineering, a failed attempt that many people
still believe in. (The other failure of the book is in educating people to
blindly believe that applying a given pattern is always a good solution
because, hey, it's a pattern)

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.

~~~
saraid216
In my experience, GoF is most useful in that it says, "Patterns exist in
software architecture as much as they do in physical architecture."

The rest is details.

------
nateberkopec
If both definitions of 'delegation' end up having the same purpose, does it
really matter? Why should I care that Rails' 'delegate' isn't exactly how some
guy in 1970 would've written it?

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.

~~~
dasil003
One of the traits that allows us to be competent programmers is a pedantry
about technical terminology. Why overload the concept of message forwarding
with a second term if what that term was originally coined to describe is a
useful paradigm?

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.

~~~
btilly
I agree that there are cases where pedantry is necessary for programmers. That
does not mean that pedantry is necessarily valuable.

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.

~~~
dasil003
I'm not following your point. I'm saying that true delegation as defined by
the article is in fact a useful tool for good software design. Maybe not as
broadly useful as standard message forwarding, but something which deserves
its own term.

~~~
btilly
Delegation as defined by the article makes every method call made by the
delegated to class part of the programming interface that you need to be aware
of when choosing to delegate. Delegation as defined by GoF makes only a
specified set of callbacks be part of that interface.

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.

------
ehosca
i don't know about you but i'm getting sick and tired of these "marketing"
posts with sensational titles.

if you have a book to sell just say so, so we can directly skip your post.

~~~
usr
I'm getting sick of them as well. Most of them follow the same formula by
having a declarative statement pointing out that someone is either wrong or
doesn't understand something or this that or the other will never work. They
seem to be pretty popular on here though as many of them have lots of
comments.

------
peeters
Terminology arguments aside, I remember at least one occassion where I really
wanted this in a GoF pattern.

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".

------
daemin
Correct me if I am wrong, but it seems to me that (Lieberman) delegation is
quite a dangerous concept when applied to the most popular object oriented
languages. You're effectively calling another object's methods and
masquerading yourself as that object, or to put it another way you're exposing
all of your privates and implementation details to another object. Hence it is
much more dangerous, and potentially quite incorrect, than just forwarding.

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.

~~~
raganwald
Liberman deleation is fine-grained multiple inheritence. If I say I'm
delegating the implementation of method foo to object bar, it sounds unsafe.
If I say I'm inheriting the implementation of method foo from object bar, it
seems safer, albeit not "classical OO."

~~~
daemin
Thanks, that makes far more sense to me.

------
alexyoung
In my experience most implementations either have a way of binding the context
per method (JavaScript), or use a loose convention of passing the sender as
the first argument (Objective-C).

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.

------
mlvljr
God bless that OO dreamers!

Always witty, and always far away from their evading (and silver :)) target...

------
sirfried
he's just selling a book, relax

------
jcmoscon
Maybe the need of a Design Pattern means that the language is not powerful
enough.

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/>

~~~
jcmoscon
Discussion about this here:
[http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatu...](http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures)

