Interfaces with default implementation – Mixins with AspectJ

Some weeks ago, I implemented several classes for the CQRS Meta Model. I found myself repeating the same code over and over again, as it was not possible to extend the same base class.

Damn… I wished Java had Mixins! After a short look a Qi4j, which seems a bit too heavy for my little use case, I remembered AspectJ’s Inter-type declarations. You can declare members (fields, methods, and constructors) that are owned by other types!

So here we go – Let’s define some behavior:

/**
 * Something that has a comment.
 */
public interface Commentable {

    public void setComment(String comment);

    public String getComment();

}

Now we’re going to create an aspect that provides the default implementation for the above interface:

/**
 * Implements the behavior of an object that has a comment assigned.
 */
public aspect CommentableAspect {

    private String Commentable.comment;

    public final String Commentable.getComment() {
        return this.comment;
    }
    
    public final void Commentable.setComment(final String comment) {
        this.comment = comment;
    }
}

All you have to do now is to implement the interface:

/**
 * Class with a comment field. 
 */
public class TestClass implements Commentable {

    // All methods are already implemented by 
    // simply adding the interface!
    
}

That’s it! All the necessary fields and methods are now added by AspectJ. You can now concentrate on composing behavior instead of thinking about a hierarchy of subclasses.

If you’d like to, it’s also possible to override the provided default methods (Caution: You’d have to remove the “final” from the aspect!) . I personally prefer the Design for Extension principle, and my methods are always abstract, final, or have an empty implementation.

Advertisements

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