Groovyスクリプトを実行する拡張機能を追加するJavaアプリケーションがあります。これまでのところ、構文解析、コンパイル、実行は問題ありません!複数のデリゲートの処理
簡素化の理由から、groovyの構文はできるだけシンプルにしたい(例:OOスキルは必要ありません)。さらに、Groovyスクリプトは、Javaクラスによって初期化されたライブラリ関数にアクセスできるものとする。これは、@Delegate
が出場する部分です!
public interface GroovyService { }
MyService.java
public class MyService implements GroovyService {
public static final MyService INSTANCE = new MyService();
private MyService() { /* ... */ }
public void method1() { /* ... */ }
public void method2() { /* ... */ }
}
GroovyService.java
:
現在、私は私のために完全に満足していない2つの異なる解決策を思い付きましたソリューション#1 - 委任された各メソッドについて、 Dショートカット
ServicesFacade.java
public class ServicesFacade {
public static final ServicesFacade INSTANCE = new ServicesFacade();
@Delegate MyService myService;
// Further @Delegate of services ...
private ServicesFacade() {
myService = MyService.INSTANCE;
}
}
GroovyScript.groovy
def method1 = myService.&method1
def method2 = myService.&method2
if (method1()) {
method2()
}
方法ショートカットとコード部はかっこいいファイルから読み取られた文字列の結果の前に付加することができますコンテンツ。ショートカットがなければ、それは私の期待を満たすだろうが、すべてのショートカットを追跡する必要がないソリューションを探している。
溶液#2 - サービスタイプのリストとメソッドのワイルドカードへのアクセスを使用し
ServicesFacade.java
public class ServicesFacade {
public static final ServicesFacade INSTANCE = new ServicesFacade();
@Delegate private final List<GroovyService> services = new ArrayList<>();
private ServicesFacade() {
this.services.add(MyService.INSTANCE);
}
public void addService(GroovyService service) {
this.services.add(service);
}
}
GroovyScript.groovy
if (services*.method1()) {
services*.method2()
}
このソリューションの利点は次のとおりです。私は任意のサービス(サービス*)に固定されたメンバー名を使用できますが、構文にはあまり感心しません。次のように
グルーヴィーなスクリプトが使用されています。
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.setScriptBaseClass(DelegatingScript.class.getName());
GroovyShell groovyShell = new GroovyShell(compilerConfiguration);
DelegatingScript script = (DelegatingScript) groovyShell.parse(fileContent);
if (script != null) {
script.setDelegate(ServicesFacade.INSTANCE);
scripts.add(script);
}
/* ... */
scripts.forEach(s -> {
s.run();
});
は委譲メソッドの直接メソッド呼び出しを達成するための良い方法はありますか?