Showing posts with label jdk7. Show all posts
Showing posts with label jdk7. Show all posts

Thursday, November 22, 2007

Followup to Feature request for JDK7: delegation

A followup to Feature request for JDK7: delegation.

In the comments to my post requesting better IOC support in JDK7 Sam asks, "The keyword *is* needed... what if the delegate is editing the behaviour of one of the methods? Perhaps to do some logging. You can't do that with the original code." For some context, he refers to code like this:

class Scout implements Camper {
    public void camp() { ... }
}

class BoyScout implements Camper {
    BoyScout(Scout scout) {
        this = scout;
    }

    public void camp() {
        callHomeFirst();
        ??? // How to forward to delegate?
    }
}

I've thought about this for a bit and I think I would go with this:

public void camp() {
    callHomeFirst();
    Camper.this.camp();
}

Why?

I have several reasons:

  1. It introduces no new syntax or keywords.
  2. It does not collide with any existing use.
  3. It is reminiscent of inner class access to their outer containing class this.

My first impulse was for some kind of casting:

((Camper) this).camp();

But this is just ugly! Then using the JLS calls qualified this occurred to me, this:

Camper.this.camp();

Tuesday, October 23, 2007

Feature request for JDK7: delegation

Some while back I wrote about delegation for Java. Delegation? By this I mean direct language support for constructor-based dependency injection of interface implementation, a.k.a. mixins.

Many interesting proposals for JDK7 are in the air: the smell of change is replacing the mustiness of an aging language and I want my chance to improve Java while there is a open window of opportunity.

About delegation

For more details follow my three-year old posting. In a nutshell, delegation is assignment to this in a constructor to inject an interface implementation without the need for manually coding boilerplate forwarding methods.

An example makes this more clear:

interface Blogger {
    boolean post(final String entry);
}

// Without delegation
class MessyCoder implements Blogger {
    private final Blogger bloggerDelegate;

    MessageCodeBlogger(Blogger bloggerDelegate) {
        this.bloggerDelegate = bloggerDelegate;
    }

    public boolean post(final String entry) {
        return bloggerDelegate.post(entry);
    }
}

// With delegation
class CleanCoder implements Blogger {
    CleanCoder(Blogger bloggerDelegate) {
        this = bloggerDelegate;
    }
}

In an example this small, the gain in clarity and bug-avoidance is limited, but for larger interfaces or for multiple interfaces, the gain is proportionately larger.

The bigger picture

Providing cleaner code is only a small benefit of delegates. A larger benefit is that of mixins: dynamic implementation inheritance without breaking the single-inheritance contract of Java. Extension by composition—rather than inheritance—becomes a first-class syntax citizen of the language.

Delegates solve the mixin problem raised by Bruce Eckels about Java generics, and do so without needing aspects. (Although, behind the scenes, the compiler very well may use aspects to implement delegates. But you the over-committed programmer need not spend your short time on this point.)

Of course, you could always just fake it or do it the hard way.

UPDATE: More thoughts here and another solution.