Monday, May 24, 2010

Mixin in Groovy and Java

Mixin is the ability to mix certain functionalities into other classes, i.e. to add new methods into other classes.

Because of the dynamic nature of Groovy, it's very straightforward to use mixin in Groovy. All we need to do is to call mixin in a class that we want to mix in as shown in the example below.

class Laughable {
    def laugh() {
        println "Hahaha"
    }
}

class Person {
}

Person.mixin(Laughable)

Person person = new Person()
person.laugh()

In Java, however, it's not that straightfoward to implement mixin. Luckily, we have AspectJ that can help to do that. Here I'm gonna show you how to use mixin using @AspectJ syntax.

Laughable.java
package myproject;

public interface Laughable {

    public void laugh();
}

LaughableImpl.java
package myproject;

public class LaughableImpl implements Laughable {

    @Override
    public void laugh() {
        System.out.println("Hahaha");
    }
}

Person.java
package myproject;

public class Person {
}

All we need here is to declare @DeclareMixin annotation.

LaughableAspect.java
package myproject;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareMixin;

@Aspect
public class LaughableAspect {

    @DeclareMixin("myproject.Person")
    public Laughable identifiable() {
        return new LaughableImpl();
    }
}


The ugly part here is that we need to typecast the person object into Laughable interface.
Main.java
package myproject;

public class Main {

    public static void main(String[] args) {
        Person person = new Person();
        Laughable laughable = (Laughable) person;
        laughable.laugh();
    }
}

No comments:

Post a Comment