Java 7での呼び出しの連鎖?
-
06-07-2019 - |
質問
Java 7プレビュープレゼンテーション(pdf)を読んでいたところ、 Chained Invocation のスライド。スライドで使用されている例は次のとおりです。
// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();
// Construction with chained invocation
Drink margarita = new DrinkBuilder()
.add("tequila")
.add("orange liqueur")
.add("lime juice")
.withRocks()
.withSalt()
.drink();
そして、私はこれについて複雑な感情を持っています。 1つのステートメントに多くのメソッド呼び出しをチェーンしないでください。一方、 margarita.this()
と margarita.that()
を記述することもあまり便利ではありません。
今、Delphiの世界からJavaに来ています。また、Delphiには with
があります。言語構成。これは少数の人に大事にされ、多くの人に嫌われています(または逆ですか?)。 with
は、連鎖呼び出しのアイデアよりもエレガントであると思います(呼び出したオブジェクトへの参照を返す void
メソッドに基づいて動作すると思います) void
は nothing を返す必要があるため、これは私が好まない部分です。
Javaで採用されている with
言語機能に感謝するため、サンプルコードは次のように記述できます。
Drink margarita = null;
with (new DrinkBuilder()) {
add("tequila");
add("orange liqueur");
add("lime juice");
withRocks();
withSalt();
margarita = drink();
}
この呼び出しをチェーン呼び出しよりも好むのは私だけですか?他の人は、 with
がJava言語の便利な拡張機能であると感じていますか? (" Java ++"の必要性に関する誰かの質問を思い出させます...)
解決
with with ステートメントは、初期化された匿名クラスを使用してJavaで翻訳できます:
Drink margarita = new DrinkBuilder() {{
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
}}.drink();
このイディオムを使用することのマイナス面は、こちらで十分に文書化されています。
Chained Invocationは、メソッドチェーンのエイリアスです。これはよく知られているイディオムであり、Javaのどのバージョンでも動作します。
class Chained {
public Chained withFoo() {
// ...
return this;
}
public Chained withBar() {
// ...
return this;
}
}
JDK 7の提案は、 void戻り型にもチェーンメソッドを許可するです。
class ChainedJava7 {
public void withFoo() {
// ...
}
public void withBar() {
// ...
}
}
他のヒント
これは興味を引くかもしれません。
その形式の with
ステートメントは非常に好きですが、VBバージョンのステートメントが好きです:
With testObject
.Height = 100
.Text = "Hello, World"
.ForeColor = System.Drawing.Color.Green
End With
With
ブロックの各属性の前に。
を付ける必要があるため、たとえばローカル変数ではなく、Objectプロパティを参照していることがわかります。 、名前空間の衝突を減らします。
例を挙げると:
with (new DrinkBuilder()) {
add(“tequila”);
add(“orange liqueur”);
add(“lime juice”);
withRocks();
withSalt();
margarita = drink();
}
withSalt()
が DrinkBuilder
のメソッドであるか、ローカルクラスのメソッドであるかを確認する簡単な方法はありません。 with
ブロックで with
-edオブジェクトのメソッドのみを許可する場合、それらははるかに有用でなくなると思います。
私は、この with
の使用が好きではありません。 Pythonの with
ステートメントが非常に好きです。ただし、 void
は void
を意味することに同意します。あなたが提供する例では、メソッド呼び出しを本当に連鎖させたい人は、メソッドの戻り値の型を変更するだけで、連鎖可能になります。
1つのオブジェクトに対する多くの呼び出しは、一部のコードを移動する必要がある兆候でしょうか?