関数の数珠つなぎ もしくは インタフェースの数珠つなぎ
JavaScriptで書いた関数の数珠つなぎ(http://d.hatena.ne.jp/taedium/20120310/p2)ですが、Javaでもやってみました。
JavaScript版とまったく同じ処理ではないですが、ある関数の実行結果を次の関数の引数としています。当然、型の制約を受けたりクロージャが使えなかったりするのでJavaScriptほど柔軟にはいかないですが、同じようなことができますね。
もうすこし汎用的にしようとすると、Func1
package example; import java.util.Arrays; import java.util.Collections; import java.util.List; public class Main { public static void main(String[] args) { Func func = chain(Arrays.asList(new A(), new B(), new C())); func.invoke("hoge"); } private static Func chain(List<Func> functions) { Collections.reverse(functions); Func next = new NullFunc(); for (final Func func : functions) { next = new AbstractFunc(next) { @Override public String invoke(String arg) { String result = func.invoke(arg); return this.next.invoke(result); } }; } return next; } public interface Func { String invoke(String arg); } public static class NullFunc implements Func { @Override public String invoke(String arg) { return null; } } public static abstract class AbstractFunc implements Func { protected Func next; public AbstractFunc(Func next) { this.next = next; } } public static class A implements Func { @Override public String invoke(String arg) { System.out.println("A is called. arg: " + arg); return "aaa"; } } public static class B implements Func { @Override public String invoke(String arg) { System.out.println("B is called. arg: " + arg); return "bbb"; } } public static class C implements Func { @Override public String invoke(String arg) { System.out.println("C is called. arg: " + arg); return "ccc"; } } }
実行結果はこうなります。
A is called. arg: hoge B is called. arg: aaa C is called. arg: bbb