Go Does Delegates Beautifully!

06 Apr, 2012 · 2 min read · #golang #ruby #delegates #java

When working with object-oriented languages, there are many instances when one would want to implement an interface re-using code from another implementation of the interface. While inheritance will work, it couples the new implementation to the specific other implementation. Composition with delegation will be a better way of doing this.

Let’s consider an application which deals with doors of different shapes. You’d have a Door type and a Shape interface implemented by different concrete shapes. You’d also have a DrawingSurface which takes any implementation of Shape and invokes draw() and fill() on it passing a graphics context.

Here’s the verbose and repetitive code you’d have in Java with neither delegates nor any form of duck-typing.

interface Shape {
    public void draw(GContext ctx);
    public void fill(GContext ctx);
}

class Door implements Shape {
    private Shape shape;

    public Door(Shape shape) {
        this.shape = shape;
    }

    public void draw(GContext ctx) {
        shape.draw(ctx);
    }

    public void fill(GContext ctx) {
        shape.draw(ctx);
    }
}

In a dynamic language with meta-programming like Ruby, this is less verbose but the delegates still need to be explicitly defined. The forwardable library defines the specified methods on Door to invoke corresponding methods on @shape at run-time. However, tools like IDEs can’t recognize Door as an implementation of Shape unless they handle the specific library call as a special case.

require 'forwardable'

class Door
    def_delegators :@shape, :draw, :fill

    def initialize(shape)
        @shape = shape
    end
end

Go gives you delegates with no extra work. You just say Door has a Shape and you get statically checked and compiled delegation.

type Shape interface {
    draw(ctx GContext)
    fill(ctx GContext)
}

type Door struct {
    Shape
}

This has all the compile-time safety checks of Java with the expressiveness of Ruby. This is one of the many cases where Go’s simple design makes code less verbose!

If you liked what you read, consider subscribing to the RSS feed in your favourite feed reader.