Groovy @Delegate annotation

Posted on December 9, 2009. Filed under: Groovy |

Groovy 1.7 provides some nice new annotations. One of those annotations is the @Delegate. What it essentially does, is providing the methods of the Delegate to the class using the Delegate. This is best explained by a small example:

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Employee employee = new Employee()
}

manager = new Manager()
assert "work!" == manager.doWork()

This works really nice. The Manager now delegates the call for doWork() to the Employee. This is quite powerful, and works really nice and easy.

However, what happens when the Manager has two delegates?

class Cleaner {
   def clean() { "clean" }
   def doWork() { "doWork" }
}

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Cleaner cleaner = new Cleaner()
   @Delegate Employee employee = new Employee()
}

manager = new Manager()

assert "work!" == manager.doWork()
assert "clean" == manager.clean()

This also works really nice. Now the Manager has two delegates, and it can delegate the clean method to the Cleaner, and the doWork method to the Employee. However, since I’m quite curious, and had a small twiscussion with @darthvader42 on this: what happens when the names of the Delegates clash, ie. the Cleaner and Employee both have a method with the same name. This is demonstrated below:

class Cleaner {
   def doWork() { "clean" }
}

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Employee employee = new Employee()
   @Delegate Cleaner cleaner = new Cleaner()
}

manager = new Manager()

assert "work!" == manager.doWork()
assert "clean" == manager.doWork()

This fails! Argh! What happens? The console output is fortunately very clear:


assert "clean" == manager.doWork()
| | |
| | work!
| Manager@2e6a54f9
false

What happened, is that Groovy picked the first Delegate it encountered, and uses those methods. The Cleaner doWork is not called anymore, since all calls to doWork are handled by the Employee.

Conclusion
The @Delegate is a very handy annotation to handle some of the plumbing code for you, but just beware of the results when using more than two @Delegates. Btw, while writing this conclusion, I was also curious what would happen if the Manager itself has a doWork method. As I expected, the doWork method of the Manager takes precedence over that of it’s delegates, so the doWork method of the Manager itself is called!

Advertisements

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

4 Responses to “Groovy @Delegate annotation”

RSS Feed for Don’t mind the language Comments RSS Feed

Good examples and use cases, cheers! Would I be correct in saying this is pretty much enabling multiple inheritance?? Well inheritance is probably how one would have achieved this in the ‘past’ i would imagine

I think it is, but with a little less coupling than really extending it, though the difference is negligible. So yes, I think it’s multiple inheritance, and yes, you have to be careful when using this 🙂

If the manager’s doWork method takes presedence, it’s easy to just programatically call the right delegate method.

But… there’s no doWork method in the Manager class. That’s the beauty of it!


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...

%d bloggers like this: