Mixin的なもの
普段使いのRubyでは、ModuleのMixinによって実装の継承ができて大変嬉しいのですが、Javaの場合はできなさそうで少し悲しいなぁ、と思っていたところSpring AOPをつかうとそれっぽいことができそうなので試してみました。
まず、Mixinのことなど何も知らないUserクラスがあるとします。nameしか情報を持っていません。
package com.hoge; public class User { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } }
で、これに年齢に関する機能をつけたい場合、Spring AOPのIntroductionを使って、Ageインターフェースと...
package com.hoge; public interface Age { void setAge(int age); int getAge(); }
AgeMixinクラスを作ります。
package com.hoge; import org.springframework.aop.support. DelegatingIntroductionInterceptor; public class AgeMixin extends DelegatingIntroductionInterceptor implements Age { private static final long serialVersionUID = 1L; private int age; @Override public int getAge() { return age; } @Override public void setAge(int age) { this.age = age; } }
で、これらをくっつけます。
package com.hoge; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support. DefaultIntroductionAdvisor; public class Main { public static void main(String[] args) { ProxyFactory beanFactory = new ProxyFactory(new Class[] { Age.class }); beanFactory.setProxyTargetClass(true); beanFactory.addAdvisor( new DefaultIntroductionAdvisor(new AgeMixin())); beanFactory.setTarget(new User()); User user = (User) beanFactory.getProxy(); user.setName("komamitsu"); System.out.println(user.getName()); ((Age) user).setAge(18); System.out.println(((Age) user).getAge()); } }
setAge()を呼ぶときにAgeクラスにキャストしているところが悲しいですが、気を取り直して実行してみると...
komamitsu 18
と表示され、Ageの(set|get)Age()が使えているのが分かります。RubyのModuleと異なり、Mixin用のクラスは継承可能なので、もしかしたら何か嬉しいかも知れません。